Home  >  Q&A  >  body text

有关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_lee2764 days ago796

reply all(6)I'll reply

  • 伊谢尔伦

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

    Erasure means that no information about the generic parameters can be obtained inside the generic class at runtime. If the boundary is specified, the actual type of the generic variable is the boundary. The code in the poster's example does not specify the boundary, so it is erased to Object , that is, the actual runtime type of obj is Object. The reason why using the get() method does not require forced type conversion is because the compiler generates the conversion code for you during compilation. If I remember correctly, it will probably be processed after The situation is similar to String s = (String)holder.get() in the main method of Example 2. For details, the author can use javap to decompile and view.

    As for the second question, I think this is the same as whether you read the source code or not. It doesn’t affect programming if you don’t read it. But after reading it, I understand that it will be very easy to write. I am still a student, and the actual programming situation is I don’t know, just some opinions~

    reply
    0
  • 阿神

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

    Generics are only reflected in the source code, and after compilation they are equivalent to the latter example you gave. Therefore, public void test(List<String> list) and public void test(List<Integer> list) cannot be overloaded.

    reply
    0
  • 天蓬老师

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

    1. Erasure is done during compilation, when java files are compiled into class files. Java's generics can be regarded as a kind of syntax sugar, making us safer and more convenient when writing Java code.

    2. Erasure is not used in actual work. Erasure can be considered as an interpretation action of generic syntax sugar at compile time.

    reply
    0
  • 怪我咯

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

    • When using the generic class T new, T is specified as String and its member variables are also String, which does not require transformation. However, in another class whose members are Object, new
      is not specified, so transformation is required.

    • Erase is generally not used in actual work.

    reply
    0
  • 黄舟

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

    1. First of all, erasure means that generic tags are handed over to the Javac compiler to execute and work. After the code has passed the compilation period, "T" is ignored during operation, and T cannot be found in the class file. Here you indicate that the type is <String>, then the compiler will convert the T held in GenericHolder into the String type during compilation. So your get does not need to be transformed (the compiler has already recognized String).

    2. Erasure is a very important concept in generics. It can be said that if you don’t understand erasure, you don’t understand generics. What is common and relevant in actual work is the serialization and deserialization of objects, which is used in frameworks such as gson.

    reply
    0
  • 怪我咯

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

    in GenericHolder<String>

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

    is equivalent to

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

    Actually, it’s just syntactic sugar

    reply
    0
  • Cancelreply