我可以在Java中的ArrayList <T>实例上使用类字段吗?

mar*_*ark 7 java generics reflection

我有这个代码,编译:

new TypeToken<ArrayList<ServerTask>>() {}.getType()
Run Code Online (Sandbox Code Playgroud)

然后我试过了

ArrayList<ServerTask>.class
Run Code Online (Sandbox Code Playgroud)

哪个不编译.

我是Java编程新手(来自C#),我认为这T.classtypeof(T)C#完全相同.显然有一些我不理解的基本内容,所以我的问题是什么是错的,ArrayList<ServerTask>.class我别无选择,而是使用new TypeToken<ArrayList<ServerTask>>() {}.getType()?是否有更短(更好,更健全)的形式?

谢谢.

Bri*_*128 11

不幸的是(?)Java使用Type Erasure实现泛型.

这意味着没有构造来获取泛型类型,并且在运行时,您的ArrayList实际上只存储对象.

确切地说,Java中的泛型是仅编译时的构造.它们仅在编译时保证类型安全.

编辑:我刚刚注意到这段代码 -

new TypeToken<ArrayList<ServerTask>>() {}.getType()
Run Code Online (Sandbox Code Playgroud)

这是类型擦除限制的解决方法.如果扩展具有特定类型的泛型类,则会保留类型信息.例如:

public interface List<T> {
}

public class StringList implements List<String> {
  // The bytecode of this class contains type information.
}
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您平凡地扩展了类TypeToken,导致编译器生成包含类型信息的匿名内部类.的实施TypeToken.getType()将使用反射来给你这个类型的信息.

编辑2:有关更详细的解释,请查看Reflecting Generics.