Java 8 – 构造函数参考 – 类型Select不定义此处适用的Select(DataObj)“

我定义了一个FunctionalInterface如下:

 @FunctionalInterface public interface BaseAction { public void execute(final DataObj dataObj) throws Exception; } 

然后,实现如下的类:

 public class Select implements BaseAction{ @Override public void execute(final DataObj dataObj) { //some operations on dataObj here.. } } 

当我尝试使用Java 8之前的语法实例化类时,为我编译,如下所示:

 public BaseAction getAction(final String action) { switch (action) { case "SELECT": return new Select(); //Works } return null; } 

但是,当我尝试使用Java 8语法对其进行实例化时,IDE开始抱怨我"The type Select does not define Select(DataObj) that is applicable here"

 public BaseAction getAction(final String action) { switch (action) { case "SELECT": return Select::new; //Compile error here.. } return null; } 

知道我该如何修复它?

您正在使用的不是“用于创建对象的Java 8语法”。 您正在使用对构造函数的引用,因此在某种程度上,您的两段代码之间的差异是相同的

someObject.toString()

someObject.toString

第一个实例化一个新对象,第二个实例指向用于实例化新对象的东西,但不调用它(顺便说一下, someObject::toString更精确的类比)

如果您只想实例化一个Select对象,那么只需继续使用“旧”代码,它就是您在Java 8中完成的方式。

如果要将特定构造函数传递给某些想要与使用哪个构造函数/类型无关的代码,则新语法很有用。

你可以这样做:

 public void executeBaseAction(DataObject data, Supplier baseActionSupplier) { BaseAction action = baseActionSupplier.get(); action.execute(data); } 

并称之为:

 executeBaseAction(data, Select::new); 

方法引用Select::new是对构造函数的引用,它与所需的function接口签名不匹配,接受DataObj参数并返回void

您需要Select引用来创建方法引用,但它必须引用execute方法。 这应该工作:

 case "SELECT": return new Select()::execute; 

如你所知, return new Select(); 有效,而且不那么冗长。 我仍然会使用它,但上面的方法参考应该工作。