ami*_*rkr 0 java generics type-safety
所以这是一个有点棘手的问题(对我来说)。
我有一个通用对象。将其命名为 MyObject。该对象有一个返回 T 类型的方法:
public class MyObject<T>
{
private T _t;
public MyObject(T t)
{
_t = t;
}
//...
public T get()
{
return _t;
}
}
Run Code Online (Sandbox Code Playgroud)
(显然我的“MyObject”做了更多的事情,但这就是要点)。
现在,我想要一张这种类型的地图:
Map<String, MyObject<?>> m = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
我希望能够使用一些预定义的字符串名称来获取地图,并且这些地图可以是任何 MyObject。例如,我可以调用:
m.put("map_1", new MyObject<String>("String"));
m.put("map_2", new MyObject<Integer>(new Integer(3));
m.put("map_3", new MyObject<Long>(new Long(5));
Run Code Online (Sandbox Code Playgroud)
ETC。
但是 - 这是棘手的部分 - 当我从地图中获取某些值时,我希望地图“记住” MyObject 的参数化类型。使用
m.get("map_1");
Run Code Online (Sandbox Code Playgroud)
会返回一个
MyObject<Object>
Run Code Online (Sandbox Code Playgroud)
类型,因为地图被定义为包含
MyObject<?>
Run Code Online (Sandbox Code Playgroud)
价值观。因此:
m.get("map_1").get() // <-- This is an Object, not a String!
Run Code Online (Sandbox Code Playgroud)
可以进行哪些修改(如果有),以便能够获得有关 MyObject 获取的对象的正确完整信息,以便调用最后一行 (m.get("map_1")) 将返回
MyObject<String>
Run Code Online (Sandbox Code Playgroud)
谢谢 :)
阿米尔。
Joshua Bloch 的《Effective Java》中的类型安全异构容器可能适用于此。基本上,您添加一个Class对象来表示类型。
public class MyObject<T>
{
private T _t;
private Class<T> type;
public MyObject( Class<T> type, T t)
{
_t = t;
this.type = type;
}
//...
public T get()
{
return _t;
}
public Class<T> getType() { return type; }
}
Run Code Online (Sandbox Code Playgroud)
然后你可以做这样的事情:
public <T> T get( Map<String, MyObject<?>> map, String key, Class<T> type ) {
return type.cast( m.get( key ).get() );
}
Run Code Online (Sandbox Code Playgroud)
这是安全的并且可以编译,但如果类型错误,则会抛出运行时错误。
(请注意,我实际上并没有编译它,所以我可能会出现语法错误。但大多数人不知道如何使用Class来转换对象。)
| 归档时间: |
|
| 查看次数: |
3992 次 |
| 最近记录: |