【问题标题】:Java 8 constructor method referencesJava 8 构造函数方法参考
【发布时间】:2014-10-21 23:13:05
【问题描述】:

我正在阅读 Java 8 书籍,它带有我复制的示例:

@FunctionalInterface
public interface Action {
    public void perform();
}

实施者:

public final class ActionImpl implements Action {
    public ActionImpl() {
        System.out.println("constructor[ActionIMPL]");
    }

    @Override
    public void perform() {
        System.out.println("perform method is called..");
    }    
}

来电者:

public final class MethodReferences {

    private final Action action;

    public MethodReferences(Action action) {
        this.action = action;
    }

    public void execute() {
        System.out.println("execute->called");
        action.perform();
        System.out.println("execute->exist");
    }

    public static void main(String[] args) {
        MethodReferences clazz = new MethodReferences(new ActionImpl());
        clazz.execute();
    }
}

如果调用此方法,则将以下内容打印到输出中:

constructor[ActionIMPL]
execute->called
perform method is called..
execute->exist

一切都很好,但是如果我使用方法引用而不是 perform message 方法会被打印出来!为什么会这样,我是不是错过了什么?

如果我使用此代码:

MethodReferences clazz = new MethodReferences(() -> new ActionImpl());
clazz.execute();

或者这个代码:

final MethodReferences clazz = new MethodReferences(ActionImpl::new);

这是打印出来的:

execute->called
constructor[ActionIMPL]
execute->exist

不打印异常消息或其他任何内容。我正在使用 Java 8 1.8.25 64 位。

更新

对于像我一样正在学习的读者来说,这是正确的运行代码。

我已经为调用者创建了一个类。

因为我需要实现一个空方法“从 Action 功能接口执行”,我需要将其作为参数传递给类构造函数 MethodReference 我引用了“MethodReferenceCall 的构造函数,它是一个空构造函数”,我可以使用它。

public class MethodReferenceCall {
    public MethodReferenceCall() {
        System.out.println("MethodReferenceCall class constructor called");
    }

    public static void main(String[] args) {
        MethodReferenceCall clazz = new MethodReferenceCall();
        MethodReferences constructorCaller = new MethodReferences(MethodReferenceCall::new);
        constructorCaller.execute();
    }
}

【问题讨论】:

  • 你在另一个动作中有一个未执行的动作。您可以使用 lambda MethodReferences clazz = new MethodReferences(() -> new ActionImpl().perform()); clazz.execute(); 实现您想要的

标签: java java-8 method-reference constructor-reference


【解决方案1】:

这个

MethodReferences clazz = new MethodReferences(() -> new ActionImpl());

不使用方法引用,它使用 lambda 表达式。功能接口是Action

public void perform();

所以

() -> new ActionImpl()

被翻译成类似于

new Action() {
    public void perform() {
        new ActionImpl();
    }
}

同样,在

MethodReferences clazz = new MethodReferences(ActionImpl::new);

确实使用构造函数引用的ActionImpl::new 被翻译成类似

new Action() {
    public void perform() {
        new ActionImpl();
    }
}

这个ActionImpl::new 不会调用new ActionImpl()。它解析为预期类型的​​实例,其功能接口方法被实现为调用该构造函数。

【讨论】:

  • 你能解释得更简单一点吗.. 对不起
  • @chiperortiz 方法 reference 不是方法 invocation。相反,它成为目标功能接口的主体。
  • @chiperortiz 基本上,您的第一个(工作)示例创建了一个新的ActionImpl,当调用该方法的perform 时,它会打印一条消息。第二个示例不会创建新的ActionImpl。它创建一个新对象,其类型是实现Action匿名 类。当调用该匿名类对象的perform 方法时,其perform 方法会创建一个新的ActionImpl(然后将其丢弃)。
  • 完美解释!如果 ActionImpl 实现了 2 个功能接口,它是如何翻译的?
猜你喜欢
  • 2020-10-31
  • 1970-01-01
  • 1970-01-01
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-10
  • 2019-07-09
相关资源
最近更新 更多