Dón*_*nal 11 java generics type-erasure
可能重复:
为什么在运行时Java中没有删除所有类型信息?
Java的泛型是通过类型擦除实现的,所以我认为在运行时无法获得有关参数化类型的任何信息.但是,我在杰克逊图书馆找到了以下课程.
(为了这个例子,我稍微简化了这个类)
public abstract class TypeReference<T> {
final Type _type;
protected TypeReference() {
Type superClass = getClass().getGenericSuperclass();
_type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
public Type getType() { return _type; }
}
Run Code Online (Sandbox Code Playgroud)
该类提供对其参数化类型的访问,如以下测试所示:
void testTypeReference() {
// notice that we're instantiating an anonymous subclass of TypeReference
TypeReference<CurrencyDto> tr = new TypeReference<CurrencyDto>() {};
assert tr.getType() == CurrencyDto.class
}
Run Code Online (Sandbox Code Playgroud)
这个类说明了可以在运行时检索实际类型参数(使用反射),这与Java泛型是通过类型擦除实现的概念是如何一致的?
Col*_*inD 12
具体类型参数信息在编译时已知存储在类文件中.例如,如果您的类具有返回List<String>
(而不是List<T>
!)的方法,那么该信息将在运行时可用.同样,如果你有一个班级:
public class Foo extends Bar<String> {
}
Run Code Online (Sandbox Code Playgroud)
type参数在编译时String
被硬编码Foo
.在TypeReference
类(以及所有类似的结构,如TypeLiteral
在吉斯和TypeToken
在GSON),要求你做出一个利用这个事实匿名子类的在你的代码.执行此操作时,将生成包含该信息的实际类文件,就像Foo
上面的示例一样.
欲了解更多信息,请参阅尼尔Gafter的博客文章在这里.
类型擦除更多是指您无法在运行时获取有关泛型类型实例的实际类型参数的信息(请注意,它Foo
的子类Bar<String>
没有类型变量且不是通用的).例如,如果您创建泛型类型的实例ArrayList<E>
:
List<String> foo = new ArrayList<String>();
Run Code Online (Sandbox Code Playgroud)
没有类型信息存储在该对象中.所以当你把它传递给其他方法时:
public <T> T foo(List<T> list)
Run Code Online (Sandbox Code Playgroud)
没有办法找出是什么T
.
归档时间: |
|
查看次数: |
4888 次 |
最近记录: |