搜尋

首頁  >  問答  >  主體

有关java泛型中一段简单代码 擦除知识点的疑问

  1. 下面这个程序中T 类型不是被擦除了吗?为什么使用get ( ) 方法不需要类型装换? (不适用泛型的简单代码就需要加(String) 来实现类型转换)

  2. 擦除知识点在实际编程中体现的多吗?

代码如下:

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();
  }
}
ringa_leeringa_lee2782 天前814

全部回覆(6)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-17 17:37:11

    擦除是指運行時在泛型類內部無法得到有關泛型參數的任何信息, 如果指定了邊界,泛型變量的實際類型就是邊界,樓主示例中的代碼沒有指定邊界, 所以擦出到Object , 也就是obj實際運行時的類型為Object, 之所以使用get()方法不需要強制類型轉換, 是因為編譯期在編譯時幫你生成了轉換的代碼, 如果我沒記錯的話, 大概處理之後的情況和範例2的main方法中的String s = (String)holder.get()類似, 詳細的樓主可以用javap 反編譯查看.

    對於第二個問題, 我覺著這就和看不看源碼是一個道理, 不看也不影響編程, 但是看過之後明白了, 寫起來會很得心應手, 我還是學生, 實際編程的情況就不知道啦, 一點點看法~

    回覆
    0
  • 阿神

    阿神2017-04-17 17:37:11

    泛型只在原始碼中體現,編譯後等同於你舉例的後者。所以pubic void test(List list)和public void test(List list)不能實作重載。

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-17 17:37:11

    1. 擦除是在編譯期間擦除,將 java 檔案編譯為 class 檔案時擦除。 java 的泛型,可以看成一種語法糖,使得我們在書寫java程式碼時更安全方便。

    2. 擦除在實際工作中沒有用到,擦除可以認為是泛型語法糖在編譯期的一種解釋動作。

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 17:37:11

    • 使用泛型類別T new的時候指定了T 為String其成員變數也就為String 不需要轉型, 而另一個類別為成員為Object,new
      的時候並未指定,所以需要轉型。

    • 擦除實際工作上一般不用。

    回覆
    0
  • 黄舟

    黄舟2017-04-17 17:37:11

    1.首先,擦除通俗的說是指泛型標籤是交給Javac編譯器去執行的,並且起作用的。 程式碼過完編譯期,運行期間就不管了《T》,在class檔找不到T了。 這裡你顯示了指明了類型是,那麼編譯器會在編譯期間將GenericHolder中所持有的T轉換成String類型。 所以你的get不用轉型了(編譯器已經把String辨識出來了)。

    2.擦除是泛型中很重要的概念,可以說不懂擦除就不懂泛型。實際工作中常見有關聯的是物件的序列化反序列化,如gson等框架中會被使用。

    回覆
    0
  • 怪我咯

    怪我咯2017-04-17 17:37:11

    GenericHolder<String> 中的

    private T obj;
    public void set(T obj) { this.obj = obj; }
    public T get() { return obj; }

    相當於

    private Object obj;
    public void set(Object obj) { this.obj = obj; }
    public Object get() { return (Object) obj; }
    ...
    String s = (String) holder.get();

    其實就是個語法糖

    回覆
    0
  • 取消回覆