考虑以下Java 8代码段。
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Consumer<Integer> consumer = x -> System.out.print(x);
integers.forEach(consumer);
}
什么是Consumer<Integer> consumer = x -> System.out.print(x)
越来越编译?
我知道Lambda并没有实现为匿名内部类。但是Consumer<Integer>
,因此接口x -> System.out.print(x)
必须在生成某种对象,但是尚不清楚在生成哪种对象。
Java 8中是否存在某种表示lambda表达式的新型对象?
更新 这是经过反编译的程序,该程序已使用eclipse java 8编译器编译,当您打开类文件时,以下输出来自eclipse。
看起来lambda表达式已变成包含lambda表达式的类的静态方法 private static synthetic void lambda$0(java.lang.Integer x);
// Compiled from Example.java (version 1.8 : 52.0, super bit)
public class Example {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public Example();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 7]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: Example
// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 4, Locals: 3
public static void main(java.lang.String[] args);
0 iconst_5
1 anewarray java.lang.Integer [16]
4 dup
5 iconst_0
6 iconst_1
7 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]
10 aastore
11 dup
12 iconst_1
13 iconst_2
14 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]
17 aastore
18 dup
19 iconst_2
20 iconst_3
21 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]
24 aastore
25 dup
26 iconst_3
27 iconst_4
28 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]
31 aastore
32 dup
33 iconst_4
34 iconst_5
35 invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [18]
38 aastore
39 invokestatic java.util.Arrays.asList(java.lang.Object[]) : java.util.List [22]
42 astore_1 [integers]
43 invokedynamic 0 accept() : java.util.function.Consumer [31]
48 astore_2 [consumer]
49 getstatic java.lang.System.out : java.io.PrintStream [32]
52 aload_2 [consumer]
53 invokevirtual java.lang.Object.getClass() : java.lang.Class [38]
56 invokevirtual java.lang.Class.getCanonicalName() : java.lang.String [42]
59 invokevirtual java.io.PrintStream.println(java.lang.String) : void [48]
62 getstatic java.lang.System.out : java.io.PrintStream [32]
65 aload_2 [consumer]
66 invokevirtual java.lang.Object.getClass() : java.lang.Class [38]
69 invokevirtual java.lang.Class.getTypeName() : java.lang.String [54]
72 invokevirtual java.io.PrintStream.println(java.lang.String) : void [48]
75 aload_1 [integers]
76 aload_2 [consumer]
77 invokeinterface java.util.List.forEach(java.util.function.Consumer) : void [57] [nargs: 2]
82 return
Line numbers:
[pc: 0, line: 10]
[pc: 43, line: 12]
[pc: 49, line: 14]
[pc: 62, line: 15]
[pc: 75, line: 17]
[pc: 82, line: 18]
Local variable table:
[pc: 0, pc: 83] local: args index: 0 type: java.lang.String[]
[pc: 43, pc: 83] local: integers index: 1 type: java.util.List
[pc: 49, pc: 83] local: consumer index: 2 type: java.util.function.Consumer
Local variable type table:
[pc: 43, pc: 83] local: integers index: 1 type: java.util.List<java.lang.Integer>
[pc: 49, pc: 83] local: consumer index: 2 type: java.util.function.Consumer<java.lang.Integer>
// Method descriptor #73 (Ljava/lang/Integer;)V
// Stack: 2, Locals: 1
private static synthetic void lambda$0(java.lang.Integer x);
0 getstatic java.lang.System.out : java.io.PrintStream [32]
3 aload_0 [x]
4 invokevirtual java.io.PrintStream.print(java.lang.Object) : void [74]
7 return
Line numbers:
[pc: 0, line: 12]
Local variable table:
[pc: 0, pc: 8] local: x index: 0 type: java.lang.Integer
Inner classes:
[inner class info: #96 java/lang/invoke/MethodHandles$Lookup, outer class info: #98 java/lang/invoke/MethodHandles
inner name: #100 Lookup, accessflags: 25 public static final]
Bootstrap methods:
0 : # 89 arguments: {#90,#93,#94}
}
Java 8语言规范的当前草案状态(第15.27.4章)
lambda表达式的值是对具有以下属性的类的实例的引用:
- 该类实现目标功能接口,如果目标类型是路口类型,则实现该路口的所有其他接口元素。
- 该类声明一个方法,该方法将覆盖功能接口超类型的抽象方法(以及其超接口的其他某些方法)。
- 方法的参数类型,返回类型和引发类型由接口的函数类型给出。
- 该方法的主体具有评估lambda主体(如果是表达式)或执行lambda主体(如果是块)的作用;如果期望结果,则从方法中返回。
- 该类没有覆盖上面提到的一个或多个接口的其他方法,除了它可以覆盖
Object
该类的方法之外。
请注意,除了字节代码应支持上述规范外,JLS没有说明应如何编译代码。
这样,lambda表达式返回的对象
x -> System.out.print(x);
将是遵循上述规则的类的实例。
鉴于您的评论
consumer.getClass()
返回以下类
Example$$Lambda$1/1072591677
似乎它正在生成特定于lambda表达式的类似代理的类。
奇怪的是,标记为“OK”的行编译得很好,但标记为“Error”的行失败了。它们看起来基本上是一样的。
编译正则表达式 正则表达式被编译成 RegexObject 实例,可以为不同的操作提供方法,如模式匹配搜索或字符串替换。 #python >>> import re >>> p = re.compile('ab*') >>> print p <_sre.SRE_Pattern object at 0xb76e1a70> re.compile() 也接受可选的标志参数,常用来实现不同的特殊功能和语
问题内容: for ( SomeListElement element : objectWithList.getList() ) { … } 上面的摘录翻译成什么? 我最感兴趣的是该方法调用一次还是每次迭代/元素调用一次? 问题答案: 它相当于
问题内容: 我正在研究道格·海尔曼(Doug Hellman)的“示例Python标准库”,并发现了这一点: “ 1.3.2编译表达式re包含用于将正则表达式作为文本字符串使用的模块级函数,但是编译程序经常使用的表达式更为有效。” 对于这种情况,我无法理解他的解释。他说“模块级功能维护编译后的表达式的缓存”,并且由于“缓存的大小”受到限制,因此“直接使用编译后的表达式可以避免缓存查找开销。” 如果
问题内容: 这是一段Java代码: 它不编译,什么是概率?错误:该行上有多个标记;’bool’变量上的语法错误。我希望它能打印出来。虽然根据我的教程书可以打印。 我知道它会发生短路,但如果&&双方都需要进行评估,那不是家庭作业,我正在学习Java。干杯 问题答案: 等效于:- 由于被评估为,因此第二个表达式不被评估,因为在那里您使用了 短路运算符(||) 。 因此,最后两个任务不会发生。和值和保持
我正在试用新的数据绑定库。我有一个奇怪的问题,属性的绑定没有编译。 这是xml文件的简化版本: 编译时收到以下消息: java.lang.RuntimeException:发现数据绑定错误. ****/ 数据绑定错误****msg:标识符必须具有XML文件中用户定义的类型。视图缺少它 当我删除声明时,一切都会编译(并正常工作!)。 我不知道我错过了什么