Java8:当引用的方法不是静态时,为什么引用方法不能编译?

时间:2017-10-27 13:02:56

标签: java lambda java-8

我试图找出使用lambda和ReferenceMethod之间的区别,我没有弄清楚如何引用非静态方法?

public class ReferenceMethod {

    public void main(String[] argv) {
        Thread t = new Thread(ReferenceMethod::printMessage); // CE
        Thread t2 = new Thread(() -> printMessage());
        t.start();
    }

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

5 个答案:

答案 0 :(得分:1)

非静态方法仅在定义它们的类的实例的上下文中有意义。这些类总是没有一个简单的构造函数,所以你不能期望实例创建实例,并且应该自己提供。

一旦您完成了此操作,就很容易从实例中引用它们:

ReferenceMethod myInstance = new ReferenceMethod();
Thread t3 = new Thread(() -> myInstance.printMessage());

答案 1 :(得分:1)

要引用非静态方法,您需要一个实例

  • 如果您使用静态方法(例如主要方法)调用它,您将拥有:instance::method
  • 如果您使用非连续方式调用它,您将拥有:this::method
public void refFromNonStatic() {
    Thread t = new Thread(this::printMessage); //ref non-static method in non-static context
    t.start();
}

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

public static void main(String[] argv) {
    ReferenceMethod r = new ReferenceMethod();
    Thread tStatic = new Thread(r::printMessage);   //ref to non-static in static context
    Thread t2 = new Thread(() -> r.printMessage());
    t2.start();
    tStatic.start();
    r.refFromNonStatic();
}

答案 2 :(得分:0)

尝试制作方法:

public static void printMessage() {
  System.out.println("Hello");
}

就像你不能在main中调用实例方法一样,你不能在main中使用实例方法的方法引用。

编辑: 并使您的main以:

开头
public static void main(String[] args) {
  ..
}

答案 3 :(得分:-1)

ReferenceMethod::printMessage更改为this::printMessage

答案 4 :(得分:-1)

要理解Java中的双冒号运算符,我会start here。但基本上,当你使用static将该方法附加到该特定类时,而不是该类的实例。当您删除static时,表示此类的每个实例都将使用此方法。因为您的方法static上没有printMessage(),这意味着类ReferenceMethod将没有名为printMessage()的方法,但类型为{{1}的实例会有方法ReferenceMethod

因此假设main方法实际上应该是静态的,我认为这是任何Java程序运行的要求,那么你的代码应该是这样的。我没有尝试过编译,如果我错了,请纠正我。

printMessage()