我有通用的代码片段,剥离到它的核心看起来像这样。有普通的通用接口

public interface Doubler<T> {
    T doubling (T param);
}


并且有工厂方法返回此接口的不同实例

public class DoublerFactory {

    public static void main(String[] args) {
        Doubler<String> input = produceDoubler("String");
        System.out.println(input.doubling(args[0]));
    }

    public static <T> Doubler<T> produceDoubler(String type) {
        Doubler result;
        switch (type) {
            case "Integer" : result =  new IntDoubler(); break;
            case "Float" : result = new FloatDoubler(); break;
            case "String" : result = new StringDoubler(); break;
            default: result = null;
        }
        return result;
    }


    static class IntDoubler implements Doubler<Integer> {
        @Override
        public Integer doubling(Integer param) {
            return param*2;
        }
    }

    static class FloatDoubler implements Doubler<Float> {
        @Override
        public Float doubling(Float param) {
            return param*2;
        }
    }

    static class StringDoubler implements Doubler<String> {
        @Override
        public String doubling(String param) {
            return param + param;
        }
    }
}


一切正常,除了工厂方法“ produceDoubler”的最后一行产生“未检查的分配”警告。我实际上理解为什么-我不知道如何编写此代码段,以便Java编译器对分配完全满意。

最佳答案

public static <T> Doubler<T> produceDoubler(String type) {


此签名表示的是,某人可以呼叫方想要的任何类型的produceDoubler呼叫T,而与type完全无关,并且produceDoubler可以返回适当的Doubler。当然不能。但这可能会做一些愚蠢的事情

Doubler<Color> doubler = produceDoubler("Integer");


这当然没有道理。没有一种明智的方法可以使颜色加倍,并且类型和字符串之间也没有关系。

使编译器满意的唯一方法是返回Doubler<?>,但这当然会迫使您在尝试使用Doubler时进行不安全的强制转换。

实际上,没有一种类型安全的方法可以将任意String连接到不同类型。唯一的类型安全替代方案是提起switch-在顶层执行类似

switch (type) {
   case "Double": {
      Doubler<Double> doubler = new DoubleDoubler();
      // use the doubler for everything you need to use it for
   }
   ...
}


...而无需尝试随时存储非混凝土类型的倍增器。

10-05 17:56