[英]Cannot assign valid constant(value) to a Generic Type variable
為什么以下不起作用?
void execute() {
Integer a = Integer.valueOf(1);
a = reassign(a);
D.log("a: " + a);
}
<T extends Integer> T reassign(T t) {
t = Integer.valueOf(2); // error: incompatible types: Integer cannot be converted to T
// t = (T) Integer.valueOf(2); // This works but with warning: [unchecked] unchecked cast
return t;
}
<T extends Integer> T reassign2(T t, T anotherT) {
t = anotherT; // This works without any warning.
return t;
}
我的理解是泛型方法/類/接口將被編譯為單個 class 文件,其中類型參數被替換為最合適的下限(在上述情況下為整數)。
Java 環境:java 11.0.4 2019-07-16 LTS
我的理解是泛型方法/類/接口將被編譯為單個 class 文件,其中類型參數替換為最合適的下限
您的理解是正確的,但編譯器旨在更智能地處理 generics。 如果編譯器完全按照您描述的方式設計,那么 generics 有什么意義? 我可以只寫一個采用Integer
的方法。 不需要 generics,因為無論如何編譯器只會用Integer
替換我擁有的任何類型參數。
您已指定T
必須是Integer
或Integer
的子類。 想想當T
是Integer
的子類時的情況,下面的賦值仍然有效嗎? 它不會!
t = Integer.valueOf(2); // you are assigning an instance of a superclass to a subclass variable
您可能會爭辯說Integer
不能有任何子類,因為它是final
,但編譯器並非旨在檢查這種情況下類的final
性。 在這里使用Integer
作為界限可能意味着reassign
根本不應該是通用的。
編譯器做的另一件事是在必要時插入強制轉換,但這與這個問題並不真正相關。
它不起作用的原因是編譯器無法證明T
實際上是而不是T
的子類型。 Integer 在這里是一個不好的例子,因為它是最終的,沒有人可以擴展它,但是編譯器不夠聰明,無法知道這一點並對其進行推理。
想象一下你有以下
class Foo{
}
class Bar extends Foo {
}
你像這樣調用重新分配
reassign(new Bar());
允許重新分配的地方
<T extends Foo> T reassign(T t){
t = new Foo();
return t;
}
那么這相當於說
Bar b = new Foo()
這當然是無效的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.