如何使用Java8 Supplier接口重写此工厂方法以提供正确的类型化实例?
我有一个扩展Map的简单界面:
public interface Thingy<K, V> extends Map<K, V> {}
Run Code Online (Sandbox Code Playgroud)
然后我有一个ThingyFactory类,其中包含Thingy所有实现类名的列表:
public final class ThingyFactory {
Map<String, Class<Thingy<?, ?>>> thingyclasses = new ConcurrentHashMap<>();
.....
@SuppressWarnings("unchecked")
public <K, V> Thingy<K, V> getInstance(String classname) throws ThingyException {
Thingy<K, V> thingy;
try {
thingy = (Thingy<K, V>) thingyclasses.get(classname).newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new ThingyException("Something bad happened: ", e.toString());
}
return thingy;
}
}
Run Code Online (Sandbox Code Playgroud)
我很确定我能够优雅地完成这项任务,并且没有使用供应商界面的SuppressWarnings和类加载器,但我似乎无法使模式非常正确.任何指导赞赏!
Thingy因为您使用通配符作为inside的通用类型thingyclasses,所以您实质上是在说:的类型Thingy可以是任何东西;但是,这会阻止编译器推断有关类型的任何信息,因此您需要显式强制转换。您可以Supplier稍微改进它,但您仍然会收到有关未经检查的强制转换的警告:
class ThingyFactory {
private Map<String, Supplier<Thingy<?, ?>>> providers = new ConcurrentHashMap<>();
@SuppressWarnings("unchecked")
public <K, V> Supplier<Thingy<K, V>> getInstance(String classname) {
return () -> (Thingy<K, V>) providers.get(classname);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您希望它是类型安全的,则需要完全重新设计它,并且仅在编译器能够推断类型时才使用通配符。
| 归档时间: |
|
| 查看次数: |
135 次 |
| 最近记录: |