首页 > 解决方案 > 错误:不能将原始构造函数引用与构造函数的显式类型参数一起使用

问题描述

我有以下代码:

主.java

public class Main {
  public static void main(String[] args) {
     TestProducer c = Test::<String>new;
     System.out.println(c.produce("Point"));
  }
}

测试.java

public class Test<N extends CharSequence> {
  private CharSequence name;

  public Test(N k) {
    name = k;
  }

  public String toString() {
    return name.toString();
  }
}

测试生产者.java

@FunctionalInterface
public interface TestProducer {
  public <N extends CharSequence> Test<N> produce(N str);
}

当我编译代码时,它会产生以下错误:

OpenJDK Runtime Environment (build 10.0.2+13-Ubuntu-1ubuntu0.18.04.4)
> javac -classpath .:/run_dir/junit-4.12.jar -d . Main.java Test.java TestProducer.java
Main.java:3: error: invalid constructor reference
     TestProducer c = Test::<String>new;
                      ^
  cannot use raw constructor reference with explicit type parameters for constructor
1 error
compiler exit status 1

我有以下问题:

  1. 这里的“原始构造函数引用”是什么(这里是“显式类型参数” <String>)?
  2. 为什么不能“使用原始构造函数引用和构造函数的显式类型参数”(推理/为什么这不是一个好主意)?
  3. 我该如何解决这个错误(创建一个只接受Strings 的 TestProducer)?

编辑:

关于避免错误,这是我发现的:
我可以修改TestProducer为以下内容:

@FunctionalInterface
public interface TestProducer<N extends CharSequence>
{
  public Test<N> produce(N str);
}

然后Main.java像这样改变:

public class Main {
  public static void main(String[] args) {
     TestProducer<String> c = Test::new;
     System.out.println(c.produce("Point"));
  }
}

通过这样做,c::produce只会接受Strings,这符合我对问题 3 的意图。问题 1 和问题 2 仍然不清楚。

标签: javacompiler-errors

解决方案


您将TestProducer接口定义为不是通用的,而是具有通用方法:

Test<N> produce(N str);

然后您尝试在分配中绑定特定类型:

TestProducer c = Test::<String>new;

但我现在这样说是完全有道理的:

c.produce(new StringBuilder())

必须返回 a Test<StringBuilder>,而不是 a Test<String>

您可能应该N在界面上添加类型参数。


推荐阅读