【问题标题】:Passing template parameters to Class#newInstance()将模板参数传递给 Class#newInstance()
【发布时间】:2018-04-05 19:29:36
【问题描述】:

我有以下课程:

class Processor<T> {
    void process( T request ) {...}
}

然后我调用以下代码:

Processor<String> p = Processor.class.newInstance();

Eclipse 抱怨,作为对 Processor.class.newInstance() 的警告

"类型安全:处理器类型的表达式需要不检查 转换为符合处理器"

如何为这个表达式指定模板参数?比如:

Processor<String> p = Processor.class.newInstance<String>();

【问题讨论】:

  • 暂时忘记泛型 - 在 Class 对象上调用 newInstance 代表应该给你的接口是什么?
  • Processor.class.newInstance() 返回一个 Processor (原始类型),您尝试将其分配给参数化类型。在这种情况下,您可以安全地抑制警告,但除非您了解使用泛型做什么,否则不要养成这种习惯。 :) (而且,上面的问题很重要。)
  • @cppbeginner 抱歉,我是想让它成为一个类,而不是一个接口。我更新了问题。
  • 你为什么要反思?打电话给演员。
  • 为什么不直接打电话给new Processor&lt;&gt;();?我想这是一个人为的例子,如果你只需要实例化它,我建议使用Supplier&lt;? extends Processor&lt;String&gt;&gt;

标签: java generics reflection interface


【解决方案1】:

我得到了处理器的一些未知具体实现的类对象

而不是尝试去做

Processor<String> processor = ConcreteProcessor.class.newInstance(); //warning

您可以简单地使用您拥有的类对象:

Processor<String> processor = classOfConcreteProcessor.newInstance();

根据您提到的“更大的系统”,类型信息将可用或不可用。

如果在您的情况下无法进行类型推断,您也可以

  • 必须围绕它进行构建,例如使用工厂/供应商
  • 相信自己并抑制编译器警告

【讨论】:

    【解决方案2】:

    您已通过使用 Supplier 代替在 Java 8 中获得了有关 cmets 警告原因的回答:

    class Ideone {
    
        public static void main(String[] args) {
            ProcessorFactory<Processor<String>> pf = 
                         new ProcessorFactory(Processor<String>::new);
            Processor<String> p = pf.build();
            p.process("Ciao!");
        }
    }
    
    class Processor<T> {
        void process( T request ) {
            System.out.println(request);
        }
    }
    
    class ProcessorFactory<T> {
        private Supplier<T> supplier;
    
        ProcessorFactory(Supplier<T> supplier) {
            this.supplier = supplier;
        }
    
        T build() {
            return supplier.get();
        }
    }
    

    基本上,您将生成委托给外部工厂主力,它们通过Supplier 获取类型,Processor&lt;String&gt;::new 是对构造函数的引用(参数化)。

    为了这么小的利益需要做很多工作,我不确定我是否会这样做。

    在这里演示:https://ideone.com/GxQOxG

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-22
      • 2017-01-05
      • 1970-01-01
      • 1970-01-01
      • 2010-12-26
      • 2016-12-13
      • 1970-01-01
      相关资源
      最近更新 更多