Tom Joe
Tom Joe

Reputation: 127

Java generics - Why is this assignment in the constructor illegal?

Why do I get a compiler error in this code ? How do I fix it ?

public class Container<T> {
    private T content;
    private T defaultValue;

    public <T> Container(T defaultValue){
        //Compiler error - incompatible types: T cannot be converted to T.
        this.defaultValue = defaultValue;
    }
}

After type erasure, T defaultValue would become Object defaultValue. Then why can't we assign T defaultValue to Object defaultValue ? After all, every type in Java is an Object.

Upvotes: 2

Views: 196

Answers (3)

Spidy
Spidy

Reputation: 40002

Remove the <T> from in front of the constructor. Java thinks you are trying to create a new generic. It thinks the T you have in the class statement is a different T then you have in the constructor. In Java's eyes you have T1 and T2. You are trying to assign T2 to a T1 variables. Even though they may be identical in methods, inheritance, etc... they are two distinct generics.

This is how Java interprets what you've written.

public class Container<T1> {
    private T1 content;
    private T1 defaultValue;

    public <T2> Container(T2 defaultValue){
        //Compiler error - incompatible types: T cannot be converted to T.
        this.defaultValue = defaultValue;
    }
}

What you meant to write was this. You don't need to specify T inside < > anywhere since it's included in the class syntax.

public class Container<T> {
    private T content;
    private T defaultValue;

    public Container(T defaultValue){
        this.defaultValue = defaultValue;
    }
}

Upvotes: 6

hamidreza75
hamidreza75

Reputation: 707

public Container(T defaultValue){ means that it returns value but constructors can not return any value explicitly. you can write:

Container(T content, T defaultValue) {

this is full example.

public class Test {
public static void main(String [] args) {
Container<String> container = new Container<>("value1","value2");        



}
}
class Container <T> {
    private T content;
    private T defaultValue;
Container(T content, T defaultValue) {
this.content=content;
this.defaultValue =defaultValue;
}
}

Upvotes: 0

Caleb Loera
Caleb Loera

Reputation: 94

The reason that the compiler error is produced is because of the <T> in the constructor. The presence of <T> means that the method is expecting a new generic parameter T. A generic parameter that is different from the one the class expects. Remove the <T> in the method signature and your program will compile.

Upvotes: 2

Related Questions