[英]Why can we create new instances of a generic template and not of generic type in Java?
我知道這是不可能的: new T
其中T
是由於類型擦除而導致的泛型類型。
那么為什么可以做一些new A<T>
,其中T是通用的? 例如,為什么以下編譯?
static class A<T>{
T t;
A(T t){
this.t=t;
}
}
static class B<T>{
A<T> create(T t){
return new A<T>(t);
}
}
public static void main (String[] args) throws java.lang.Exception
{
A<Integer> a = new B<Integer>().create(3);
}
因為A<Integer>
在編譯和運行時是一個定義良好的類型。
在概念上,中間步驟,之后:
new B<Integer>()
你對.create(3)
調用相當於調用:
static class B {
A<Integer> create(Integer t){
return new A<Integer>(t);
}
}
擦除后, A<Integer>
變為A
,這是一種有效類型。
你不能做new T
因為T
不是一個定義良好的類型,它只是一個標記。 如果你真的需要,你可以獲得相應的類並使用類似的東西實例化類型為T
的對象:
public class GenericFactory {
<T> T create(Class<T> c) throws Exception {
return c.newInstance();
}
}
並使用它像:
new GenericFactory().create(Integer.class);
是的,那很難看。
由於類型擦除,您可以實例化new A<T>()
。 如果Java將Generics實現為可再生,那么如果沒有用於查找T
的運行時綁定的反射,這將無法工作。
通過擴展,這是由於對象類型的非泛型方面被實現(可以用getClass()
訪問),編譯器不可能發出這樣的字節碼,它能夠實例化任何類型T,具體取決於通話網站。
您沒有創建通用模板的新實例。 您正在使用通用模板創建對象實例。
new A<T>(t);
創建一個新的A
,這不是通用的。 在編譯時你不一定知道T
是什么,但是你知道對象將是A
事實上,它的美妙之處在於你不必預知T
將會是什么,它允許你創建如此強大的代碼,這些代碼將是可重用的。 想象一下,如果你實現了一個Stack
,那么你對實際的內容類型不感興趣。 您有興趣處理top
, pop
, push
操作。 如果您不必預測元素是Integer
, String
還是其他類型,您可以優雅地編寫適用於許多不同類的通用代碼。
如果我不得不預知T
是什么,那么我寧願說它是一個Object
,然后能夠處理任何對象。 事實上我相信這樣的事情會在后台發生。 另外,另一種選擇是使用reflection
,但這根本就不干凈。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.