Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用双冒号(:)在ExecuterService中调用方法_Java_Multithreading_Java 8_Concurrency_Executorservice - Fatal编程技术网

Java 使用双冒号(:)在ExecuterService中调用方法

Java 使用双冒号(:)在ExecuterService中调用方法,java,multithreading,java-8,concurrency,executorservice,Java,Multithreading,Java 8,Concurrency,Executorservice,我有一个类分别由静态和非静态两个方法组成,根据我的有限知识,提交方法直接或通过lamba表达式接受可运行、可调用的实例 今天我了解到,我们甚至可以使用Java8中添加的双冒号直接调用或触发静态和非静态方法 我只是想知道这是如何工作的,我的类中没有run方法,它也没有实现runnable,甚至我没有使用lamba 使用::是一种好的做法,还是应该传递可运行或可调用的实例 有没有其他方法可以在submit()中调用方法而不是传递实例 Class A { public static void pri

我有一个类分别由静态和非静态两个方法组成,根据我的有限知识,提交方法直接或通过lamba表达式接受可运行、可调用的实例

今天我了解到,我们甚至可以使用Java8中添加的双冒号直接调用或触发静态和非静态方法

我只是想知道这是如何工作的,我的类中没有run方法,它也没有实现runnable,甚至我没有使用lamba

使用::是一种好的做法,还是应该传递可运行或可调用的实例

有没有其他方法可以在submit()中调用方法而不是传递实例

Class A {

public static void printSomething(){
System.out.println("Staitc Method");
}

public void print()
{
System.out.println("Non-Staitc Method");
}

}

psvm()
{
A a = new A():
ExecutorService es = Executors.newFixedThreadPool(2);
es.submit(A::printSomething);  //Expected is runnable or callable task
es.submit(a::print);
}


A::printSomething
称为方法引用。当您在需要Runnable或Callable等接口的地方使用方法引用时,Java会自动创建调用该方法的接口的实现

就是

es.submit(A::printSomething);
行为与

es.submit(new Runnable() {
    public void run() {
        A.printSomething();
    }
});
但是更易于阅读,并且不会在使用它的任何地方创建新类,也不会在每次调用它时创建新的对象实例

您可以在中阅读有关方法引用的更多信息

实现这一点的另一种方法是使用lambda表达式,例如:


由于
Runnable
是一个函数,因此即使方法名称不匹配,也可以使用适合它的lambda表达式或方法引用。因此,任何无参数void方法都可以用作
可运行的

Runnable r1 = () -> a.printSomething();
Runnable r2 = A::printSomething();  // Method reference, short-hand
Runnable r3 = () -> A.printSomething(); // Same as r2, but as explicit lambda expression

即使类没有实现
void run()
方法,方法引用仍然有效的原因是函数接口分配的关键是方法签名,而不是方法名称

A
printSomething
的方法签名与
Runnable
run
匹配,因此它可以工作。请注意,这只适用于功能接口(即只有一个方法的接口,所述方法没有默认实现)

这是个好习惯吗?这是一个风格问题,但使用方法引用肯定不是一个坏习惯,而且它们比
left->right
lambdas更简洁

我建议你自己试试,这样你就清楚了规则

public class FunctionalInterfaceDemo {

  public static class SimpleClass {
    public static void doItStatic() {
    }

    public void doItNonStatic() {
    }
  }

  interface MyOwnFunctionalInterface {
    void methodA();
  }

  interface NotAFunctionalInterface {
    void methodA();

    void methodB();
  }

  interface AlsoNotAFunctionalInterface {
    default void methodA() {
    }
  }


  public static void main(String[] args) {
    MyOwnFunctionalInterface compiles = SimpleClass::doItStatic;
    MyOwnFunctionalInterface alsoCompiles = new SimpleClass()::doItNonStatic;
    NotAFunctionalInterface doesNotCompile = SimpleClass::doItStatic;
    AlsoNotAFunctionalInterface alsoDoesNotCompile = SimpleClass::doItStatic;
  }

}

您可以
es.submit(()->{//code/invoke a void method here})
run
方法调用您的
print
方法。@Naman这是lambda表达式,它可以工作,间接地说,它是run方法,但是::如何工作?链接的问题很好地回答了不同答案中的不同示例。是的,关键术语是“函数接口”1+对于不同的方法,每次使用方法引用是一种好的做法吗?@Shelly我想这取决于你问谁。对于无参数的方法来说,这没有多大区别,但是当方法有参数时,使用显式版本
(a,b)->foo(a,b)
this::foo
,例如在使用流时,它会变得更清晰。@Kayaman感谢manYou示例真的很有帮助
public class FunctionalInterfaceDemo {

  public static class SimpleClass {
    public static void doItStatic() {
    }

    public void doItNonStatic() {
    }
  }

  interface MyOwnFunctionalInterface {
    void methodA();
  }

  interface NotAFunctionalInterface {
    void methodA();

    void methodB();
  }

  interface AlsoNotAFunctionalInterface {
    default void methodA() {
    }
  }


  public static void main(String[] args) {
    MyOwnFunctionalInterface compiles = SimpleClass::doItStatic;
    MyOwnFunctionalInterface alsoCompiles = new SimpleClass()::doItNonStatic;
    NotAFunctionalInterface doesNotCompile = SimpleClass::doItStatic;
    AlsoNotAFunctionalInterface alsoDoesNotCompile = SimpleClass::doItStatic;
  }