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();
有效,而且不那么冗长。 我仍然会使用它,但上面的方法参考应该工作。