Java lambda方法和新的Object

时间:2018-04-30 09:03:25

标签: java lambda java-8

我有以下代码:

public class RefDemo {

    static class Demo implements Runnable {

        public Demo() {
            System.out.println(this.toString() + "-----");
        }

        @Override
        public void run() {
            System.out.println("run");
        }
    }

    public static void main(String[] args) {
        Runnable runnable = Demo::new; // lambda ref constructor method
        runnable.run(); // does not do anything
        System.out.println(runnable);
        Runnable demo = new Demo(); // using new to create a Demo instance
        demo.run();
        System.out.println(demo);
    }
}

打印哪些:

RefDemo$Demo@7291c18f----- // lambda run constructor method print
RefDemo$$Lambda$1/793589513@34a245ab // main method print
RefDemo$Demo@7cc355be-----
run
RefDemo$Demo@7cc355be

我不知道调用run

时代码无法打印runnable.run();的原因

为什么会这样?

4 个答案:

答案 0 :(得分:40)

此代码

Runnable runnable = Demo::new;

等同于此代码

Runnable runnable = new Runnable() {
    @Override 
    public void run() {
        new Demo();
    }
};

因此,您不是指run的{​​{1}}方法,而是指构造函数。

答案 1 :(得分:20)

您只是在太多地方使用Runnable并让自己感到困惑。以下代码使发生的事情更加清晰:

public class RefDemo {

    static class Demo {

        public Demo() {
            System.out.println(this.toString() + "-----");
        }

        public void something() {
            System.out.println("something");
        }
    }

    public static void main(String[] args) {
        Runnable runnable = Demo::new; 
        runnable.run();

        System.out.println(runnable);

        Demo demo = new Demo();
        demo.something();

        System.out.println(demo);
    }
}

Runnable runnable = Demo::new;表示您现在引用了Demo的构造函数(在删除与Runnable接口的一致性后仍然有效)。并且您将该引用存储在Runnable类型的变量中,该变量仅在其功能接口兼容时才有效。在该引用上调用run然后只需调用构造函数 run的{​​{1}} / something方法。

答案 2 :(得分:11)

行:

Runnable runnable = Demo::new;
runnable.run();

相当于:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        new Demo(); // Creates an instance of the Demo class, and nothing more
    }
};
runnable.run();

同时,您的意图是通过方法引用从run类调用Demo方法。因此,我认为您的意思如下:

Runnable runnable = new Demo()::run;
runnable.run();
// But, this is a little bit redundant...

以上代码相当于:

Demo demo = new Demo();
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        demo.run();
    }
};
runnable.run();

P.S。这里你真的不需要方法参考,所以只需写:

new Demo().run();

或者:

Runnable demo = new Demo();
demo.run();

答案 3 :(得分:6)

Demo::newDemo类的构造函数。由于您将其分配给对Runnable接口的引用,因此调用runnable.run()将调用构造函数并创建新的Demo实例。 <{1}}方法未执行。

如果要使用方法引用定义调用run()&n; Runnable方法的Demo实例,可以写:

run()

当然,由于Runnable runnable = new Demo()::run; 已经实现了Demo,所以写起来要简单得多:

Runnable