难以理解Java 8 Lambda

use*_*001 8 java lambda java-8

private ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
    Thread t = new Thread(r);
    t.setDaemon(true); // allows app to exit if tasks are running
    return t ;
});
Run Code Online (Sandbox Code Playgroud)

我理解遗嘱执行人背后的想法,但是,参与者r让我感到困惑.我用了:

 final ExecutorService exec = Executors.newSingleThreadExecutor(r -> {
        Thread t = new Thread(r);
        System.out.println("Class of r: " + r.getClass()+ ". r to string: " + r.toString());
        System.out.println("Class of t: " + t.getClass() +". Name of t: "+ t.getName());
        t.setDaemon(true);
        return t;
    });
Run Code Online (Sandbox Code Playgroud)

深入挖掘,结果如下:

Class of r: class java.util.concurrent.ThreadPoolExecutor$Worker. r to string: java.util.concurrent.ThreadPoolExecutor$Worker@1dc3963[State = -1, empty queue]
Class of t: class java.lang.Thread. Name of t: Thread-3
Run Code Online (Sandbox Code Playgroud)

r作为参数传递给Thread对象构造函数.

  1. 简单的字母如何r表示传递的对象是ThreadPoolExecutor
  2. 如何是一个ThreadPoolExecutor差强人意的,如果它没有实现参数Runnable所要求的通过Thread's构造函数?

如果有人能够为我提供非lambda版本的代码,那么对我的理解将是非常有益的.

Rad*_*def 15

newSingleThreadExecutor将ThreadFactory作为参数.ThreadFactory定义了一个newThread将Runnable作为参数并返回一个Thread的方法.

如果我们明确指定类型,lambda可能对你更有意义r:

(Runnable r) -> {
    Thread t = new Thread(r);
    return t;
}
Run Code Online (Sandbox Code Playgroud)

现在更明显的是这是对身体的定义newThread.

除了因为lambda立即作为参数传递给接受ThreadFactory的方法,编译器才能推断出类型r必须是Runnable.因此可以省略.

如果没有lambda,此代码将转换为以下匿名类定义和实例化:

private ExecutorService exec = Executors.newSingleThreadExecutor(
    new ThreadFactory() {
        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

简单的字母如何r表示传递的对象是ThreadPoolExecutor

类型r是Runnable,因为lambda表达式的目标类型以这种方式定义了它的单个方法.

您看到的对象实际上是一个实现Runnable的ThreadPoolExecutor的私有内部类.ThreadPoolExecutor$Worker

如何是一个ThreadPoolExecutor差强人意的,如果它没有实现参数Runnable所要求的通过Thread的构造?

见上文(r是一个Runnable).

  • 您也可以在其他类中看到美元符号,例如当您看到类名称如ClassContainingLambda $$ Lambda $ 1时,它不是内部类... (3认同)
  • 我很乐意解释它.还有很多东西要学习`$`.当您在代码中引用嵌套或内部类时,使用`Outer.Inner`但通常它实际上被编译为名为`Outer $ Inner`的类.`$`是所有标识符的有效字符,但通常被认为是为内部机制保留的.http://stackoverflow.com/q/7484210/2891664 (2认同)