Nee*_*eel 9 java generics types
我有一个POJO指定为:MyClass<U>,其中U是泛型类型参数.我正在尝试编写一个实用程序方法,它接受类引用Class<T>并填充类型Map<String, T>的地图(接受要填充的地图).
这种方法实现如下:
static void populateMap(Map<String, T> map, Class<T> type) {
...
// Parses into the specified type and returns an object of that type.
T obj = parse(..., type);
map.put (key, obj);
...
return map;
}
Run Code Online (Sandbox Code Playgroud)
编译好了.在我的调用者中,我尝试使用任何MyClass实例(无论类型)填充地图作为值.因此我使用以下代码:
// Loses type information
Map<String, MyClass<?>> m = new HashMap<>();
populateMap(m, MyClass.class);
Run Code Online (Sandbox Code Playgroud)
这不编译.编译错误:
populate(Map<String,T>, Class<T>)类型...中的方法不适用于参数(Map<String,MyClass<?>>, Class<MyClass>)
我怎样才能解决这个问题?
在这种情况下,对 进行未经检查的强制转换应该是安全的Class<MyClass<?>>:
// This is okay because we're switching to a type with an unbounded wildcard -
// the behaviors of Class.newInstance and Class.cast are still safe.
@SuppressWarnings("unchecked")
Class<MyClass<?>> classWithNarrowedType =
(Class<MyClass<?>>)(Class<?>)MyClass.class;
populateMap(m, classWithNarrowedType);
Run Code Online (Sandbox Code Playgroud)
这是一个笨拙的解决方案,特别是如果您有许多这样的调用站点,但无法回避这样一个事实,即类文字是用原始类型参数化的,这使得它们作为参数化类型的工厂使用MyClass<T>本身就很尴尬。
一个可能更清洁的解决方案将与populateMap类文字的使用解耦:
interface Parser<T> {
T parse();
}
static void populateMap(Map<String, T> map, Parser<T> parser) { ... }
...
Map<String, MyClass<?>> m = new HashMap<>();
Parser<MyClass<?>> myClassParser = new Parser<MyClass<?>>() {
@Override
public MyClass<?> parse() {
return parse(..., MyClass.class);
}
};
populateMap(m, myClassParser);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我建议使用更灵活的签名(有关更多信息,请参阅什么是 PECS(生产者扩展消费者超级)?):
static void populateMap(Map<String, ? super T> map, Parser<T> parser)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21753 次 |
| 最近记录: |