Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java8供应商接口,以提供正确的类型化实例_Java_Generics - Fatal编程技术网

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<

如何使用Java8供应商接口重写此工厂方法以提供正确的类型化实例

我有一个扩展地图的简单界面:

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
be
providers
?是的,Jacob G我将修复问题通配符与类型推断无关。嗨,Jacob-让我尝试另一种方法-忘记“提供程序”完全映射-如果我只是拥有字符串classname,有没有办法创建classname Thingy的新实例?@richards没有显式转换到
Thingy
,我对此表示怀疑,因为您的方法不是类型安全的。