dav*_*ooh 6 java generics guava
我在我的项目中使用了Guava TypeToken类,但是我得到了意想不到的结果.
我有MyGenericClass<T>:
public class MyGenericClass<T> implements MyInterface {
private TypeToken<T> recordType;
public MyGenericClass(String name) {
this.recordType = new TypeToken<T>(getClass()) {};
// ...
}
// ...
@SuppressWarnings("unchecked")
protected Class<T> getRecordType() {
return (Class<T>) recordType.getRawType();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我实例化一个对象new MyGenericClass<String>(),然后调用getRecordType()我希望得到java.lang.String,而不是我得到java.lang.Object.
但是,如果我扩展泛型类:
public class MyStringImpl extends MyGenericClass<String> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
并实例化这个新类:new MyStringImpl()然后我得到正确的结果.
为什么会这样?这是预期的行为TypeToken吗?
maa*_*nus 14
为Ian的回答添加一些无聊的细节:如果TypeToken以你期望的方式工作会很好,但这是不可能的.当你申报时
public class MyGenericClass<T> implements MyInterface {...}
Run Code Online (Sandbox Code Playgroud)
JVM看起来像
public class MyGenericClass<Object> implements MyInterface {...}
Run Code Online (Sandbox Code Playgroud)
由于擦除.
但是当你宣布时
public class MyStringImpl extends MyGenericClass<String> {...}
Run Code Online (Sandbox Code Playgroud)
然后在所用MyStringImpl的泛型的定义中记录并可以通过获得Class#getGenericSuperclass().这是(一部分)背后的魔力TypeToken.
Ian*_*rts 13
要实现此功能,您需要在实例化时使用相同的匿名子类技巧MyGenericClass:
new MyGenericClass<String>() {}
Run Code Online (Sandbox Code Playgroud)
如果你这样做,那么你会得到String回报getRecordType.这个必要的原因在该构造函数的JavaDocs中进行了TypeToken解释.
客户端创建一个空的匿名子类.这样做会在匿名类的类型层次结构中嵌入type参数,因此我们可以在运行时重新构建它,尽管擦除.
| 归档时间: |
|
| 查看次数: |
4307 次 |
| 最近记录: |