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

时间:2015-10-13 16:47:56

标签: java java-8

我定义了一个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;
}

我知道如何解决它?

2 个答案:

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