Java泛型 – 为什么构造函数中的此赋值是非法的?

huangapple go评论65阅读模式
英文:

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

问题

为什么我在这段代码中得到编译器错误?如何修复它?

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

    public <T> Container(T defaultValue){
        // 编译器错误 - 不兼容的类型:无法将 T 转换为 T。
        this.defaultValue = defaultValue;
    }
}

经过类型擦除,T defaultValue 会变成 Object defaultValue。那么为什么我们不能将 T defaultValue 赋值给 Object defaultValue?毕竟,在 Java 中每个类型都是一个对象。

英文:

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

public class Container&lt;T&gt; {
    private T content;
    private T defaultValue;

    public &lt;T&gt; 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.

答案1

得分: 6

从构造函数前面删除&lt;T&gt;。Java认为您正在尝试创建一个新的泛型。它认为您在类语句中拥有的T与您在构造函数中拥有的T不同。在Java的视觉中,您有T1和T2。您试图将T2分配给T1变量。即使它们在方法、继承等方面可能相同,它们仍然是两个不同的泛型。

这是Java解释您所写内容的方式。

public class Container&lt;T1&gt; {
    private T1 content;
    private T1 defaultValue;

    public &lt;T2&gt; Container(T2 defaultValue){
        //编译器错误 - 不兼容的类型:无法将T转换为T。
        this.defaultValue = defaultValue;
    }
}

您原本想要写的是这样的。您不需要在任何地方指定< >内部的T,因为它已包含在类语法中。

public class Container&lt;T&gt; {
    private T content;
    private T defaultValue;

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

Remove the &lt;T&gt; 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&lt;T1&gt; {
    private T1 content;
    private T1 defaultValue;

    public &lt;T2&gt; 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&lt;T&gt; {
    private T content;
    private T defaultValue;

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

答案2

得分: 2

编译器错误产生的原因是构造函数中的&lt;T&gt;&lt;T&gt;的存在意味着该方法期望一个新的泛型参数T,而这个泛型参数与类所期望的参数不同。从方法签名中移除&lt;T&gt;,你的程序将会编译通过。

英文:

The reason that the compiler error is produced is because of the &lt;T&gt; in the constructor.
The presence of &lt;T&gt; 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 &lt;T&gt; in the method signature and your program will compile.

答案3

得分: 0

public <T> Container(T defaultValue) {
    // 表示这个方法会返回一个值,但构造函数不能显式返回任何值。
}

// 你可以这样写:

Container(T content, T defaultValue) {
    // 这是完整的示例。

    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;
        }
    }
}
英文:

public <T> 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&lt;String&gt; container = new Container&lt;&gt;(&quot;value1&quot;,&quot;value2&quot;);        



}
}
class Container &lt;T&gt; {
    private T content;
    private T defaultValue;
Container(T content, T defaultValue) {
this.content=content;
this.defaultValue =defaultValue;
}
}

huangapple
  • 本文由 发表于 2020年4月7日 11:05:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/61072166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定