簡體   English   中英

為什么我們可以創建通用模板的新實例而不是Java中的泛型類型?

[英]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 ,那么你對實際的內容類型不感興趣。 您有興趣處理toppoppush操作。 如果您不必預測元素是IntegerString還是其他類型,您可以優雅地編寫適用於許多不同類的通用代碼。

如果我不得不預知T是什么,那么我寧願說它是一個Object ,然后能夠處理任何對象。 事實上我相信這樣的事情會在后台發生。 另外,另一種選擇是使用reflection ,但這根本就不干凈。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM