Java8供应商接口,以提供正确的类型化实例
如何使用Java8供应商接口重写此工厂方法以提供正确的类型化实例 我有一个扩展地图的简单界面:Java8供应商接口,以提供正确的类型化实例,java,generics,Java,Generics,如何使用Java8供应商接口重写此工厂方法以提供正确的类型化实例 我有一个扩展地图的简单界面: public interface Thingy<K, V> extends Map<K, V> {} public interface Thingy扩展了Map{} 然后我有一个ThingyFactory类,它包含Thingy的所有实现类名的列表: public final class ThingyFactory { Map<String, Class<
public interface Thingy<K, V> extends Map<K, V> {}
public interface Thingy扩展了Map{}
然后我有一个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;
}
}
公共最终类ThingyFactory{
Map因为您在thingyclasses
中使用通配符作为Thingy
的泛型类型,您本质上是说:Thingy
的类型可以是任何类型;但是,这禁止编译器推断有关该类型的任何内容,因此您需要显式转换。您可以使用Supplier
进行im稍微证明一下,但你仍然会收到关于未经检查强制转换的警告:
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);
}
}
class ThingyFactory{
私人地图有趣的挑战。我想这就是你想要的:
public class Main {
public static void main(String[] args) {
ThingyFactory<String, String> factory = new ThingyFactory<>();
Thingy<String, String> instance = factory.getInstance("ThingyImpl");
System.out.println(instance.clazzName());
Thingy<String, String> otherInstance = factory.getInstance(ThingyImpl.class);
System.out.println(instance.clazzName());
}
}
interface Thingy<K, V> extends Map<K, V> {
//added this method for testing purpuses
String clazzName();
}
//extending HashMap so I don't have to implement Map's methods
class ThingyImpl<K, V> extends HashMap<K, V> implements Thingy<K, V> {
public String clazzName() {
return "ThingyImpl";
}
}
final class ThingyFactory<K, V> {
private Map<String, Supplier<Thingy<K, V>>> providers = new ConcurrentHashMap<>();
public ThingyFactory() {
providers.put("ThingyImpl", () -> new ThingyImpl());
}
public Thingy<K, V> getInstance(String classname) {
return providers.get(classname).get();
}
// alternative with Class.
// You could change providers to a Map<Class<? extends Thingy>, Supplier<Thingy<K, V>>>
public Thingy<K, V> getInstance(Class<? extends Thingy> clazz) {
return providers.get(clazz.getName()).get();
}
}
公共类主{
公共静态void main(字符串[]args){
ThingyFactory工厂=新ThingyFactory();
Thingy instance=factory.getInstance(“ThingyImpl”);
System.out.println(instance.clazzName());
Thingy otherInstance=factory.getInstance(ThingyImpl.class);
System.out.println(instance.clazzName());
}
}
接口扩展映射{
//增加了测试紫色的方法
字符串clazzName();
}
//扩展HashMap,因此我不必实现Map的方法
类ThingyImpl扩展HashMap实现Thingy{
公共字符串clazzName(){
返回“ThingyImpl”;
}
}
末级物流工厂{
私有映射提供程序=新的ConcurrentHashMap();
公共物品工厂(){
put(“ThingyImpl”,()->newthingyimpl());
}
public Thingy getInstance(字符串类名称){
返回providers.get(classname.get();
}
//课堂上的选择。
//您可以将提供程序更改为MapInterest问题好友。这可能有用吗?是否应该将thingyclasses
beproviders
?是的,Jacob G我将修复问题通配符与类型推断无关。嗨,Jacob-让我尝试另一种方法-忘记“提供程序”完全映射-如果我只是拥有字符串classname,有没有办法创建classname Thingy的新实例?@richards没有显式转换到Thingy
,我对此表示怀疑,因为您的方法不是类型安全的。