下面这个程序中T 类型不是被擦除了吗?为什么使用get ( ) 方法不需要类型装换? (不适用泛型的简单代码就需要加(String) 来实现类型转换)
擦除知识点在实际编程中体现的多吗?
代码如下:
public class GenericHolder<T> {
private T obj;
public void set(T obj) { this.obj = obj; }
public T get() { return obj; }
public static void main(String[] args) {
GenericHolder<String> holder =
new GenericHolder<String>();
holder.set("Item");
String s = holder.get();
}
}
public class SimpleHolder {
private Object obj;
public void set(Object obj) { this.obj = obj; }
public Object get() { return obj; }
public static void main(String[] args) {
SimpleHolder holder = new SimpleHolder();
holder.set("Item");
String s = (String)holder.get();
}
}
擦除是指運行時在泛型類內部無法得到有關泛型參數的任何信息, 如果指定了邊界,泛型變量的實際類型就是邊界,樓主示例中的代碼沒有指定邊界, 所以擦出到Object , 也就是obj實際運行時的類型為Object, 之所以使用get()方法不需要強制類型轉換, 是因為編譯期在編譯時幫你生成了轉換的代碼, 如果我沒記錯的話, 大概處理之後的情況和範例2的main方法中的
String s = (String)holder.get()
類似, 詳細的樓主可以用javap 反編譯查看.對於第二個問題, 我覺著這就和看不看源碼是一個道理, 不看也不影響編程, 但是看過之後明白了, 寫起來會很得心應手, 我還是學生, 實際編程的情況就不知道啦, 一點點看法~
泛型只在原始碼中體現,編譯後等同於你舉例的後者。所以pubic void test(List list)和public void test(List list)不能實作重載。
擦除是在編譯期間擦除,將 java 檔案編譯為 class 檔案時擦除。 java 的泛型,可以看成一種語法糖,使得我們在書寫java程式碼時更安全方便。
擦除在實際工作中沒有用到,擦除可以認為是泛型語法糖在編譯期的一種解釋動作。
使用泛型類別T new的時候指定了T 為String其成員變數也就為String 不需要轉型, 而另一個類別為成員為Object,new
的時候並未指定,所以需要轉型。
擦除實際工作上一般不用。
1.首先,擦除通俗的說是指泛型標籤是交給Javac編譯器去執行的,並且起作用的。 程式碼過完編譯期,運行期間就不管了《T》,在class檔找不到T了。 這裡你顯示了指明了類型是,那麼編譯器會在編譯期間將GenericHolder中所持有的T轉換成String類型。 所以你的get不用轉型了(編譯器已經把String辨識出來了)。
2.擦除是泛型中很重要的概念,可以說不懂擦除就不懂泛型。實際工作中常見有關聯的是物件的序列化反序列化,如gson等框架中會被使用。
GenericHolder<String>
中的相當於
其實就是個語法糖