我定义了一个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..
}
}
当我尝试使用Select
之前的语法实例化类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;
}
我知道如何解决它?
答案 0 :(得分:2)
您正在使用的不是"用于创建对象的Java 8语法"。您正在使用对构造函数的引用,因此在某种程度上,您的两段代码之间的差异与之间的区别相同
someObject.toString()
和
someObject.toString
第一个实例化一个新对象,第二个实例指向用于实例化新对象的东西,但是没有将其称为(更精确的类比将是someObject::toString
,顺便说一句)。
如果您要做的只是实例化一个Select
对象,那么只需继续使用" old"代码,它完全是你在Java 8中的表现。
如果您希望将特定构造函数传递给某些想要与使用哪个构造函数/类型无关的代码,则新语法非常有用。
你可以这样做:
public void executeBaseAction(DataObject data, Supplier<BaseAction> baseActionSupplier) {
BaseAction action = baseActionSupplier.get();
action.execute(data);
}
并称之为:
executeBaseAction(data, Select::new);
答案 1 :(得分:0)
方法引用Select::new
是对构造函数的引用,它与所需的功能接口签名不匹配,采用DataObj
参数并返回void
。
您需要Select
引用来创建方法引用,但它必须引用execute
方法。这应该有效:
case "SELECT": return new Select()::execute;
正如您所指出的那样,return new Select();
有效,而且不那么冗长。我仍然会使用它,但上面的方法参考应该有用。