Tue, 14 May 2013 11:11:09 -0700
8012556: Implement lambda methods on interfaces as static
8006140: Javac NPE compiling Lambda expression on initialization expression of static field in interface
Summary: Lambdas occurring in static contexts or those not needing instance information should be generated into static methods. This has long been the case for classes. However, as a work-around to the lack of support for statics on interfaces, interface lambda methods have been generated into default methods. For lambdas in interface static contexts (fields and static methods) this causes an NPE in javac because there is no 'this'. MethodHandles now support static methods on interfaces. This changeset allows lambda methods to be generated as static interface methods. An existing bug in Hotspot (8013875) is exposed in a test when the "-esa" flag is used. This test and another test that already exposed this bug have been marked with @ignore.
Reviewed-by: mcimadamore
1 /*
2 * @test /nodynamiccopyright/
3 * @bug 8003280
4 * @summary Add lambda tests
5 * check that lambda cannot shadow variables from enclosing scope
6 * @compile/fail/ref=LambdaScope04.out -XDrawDiagnostics LambdaScope04.java
7 */
9 class LambdaScope04 {
11 interface SAM {
12 void m(Object o);
13 }
15 static SAM field1 = field1->{}; //ok
16 static SAM field2 = param->{ Object field2 = null; }; //ok
18 SAM field3 = field3->{}; //ok
19 SAM field4 = param->{ Object field4 = null; }; //ok
21 {
22 Object local = null;
23 SAM s1 = local->{}; //error
24 SAM s2 = param->{ Object local = null; }; //error
25 }
27 static {
28 Object local = null;
29 SAM s1 = local->{}; //error
30 SAM s2 = param->{ Object local = null; }; //error
31 SAM s3 = field1->{ Object field_2 = null; }; //ok
32 }
34 void testLocalInstance() {
35 Object local = null;
36 SAM s1 = local->{}; //error
37 SAM s2 = param->{ Object local = null; }; //error
38 SAM s3 = field1->{ Object field_2 = null; }; //ok
39 }
41 static void testLocalStatic() {
42 Object local = null;
43 SAM s1 = local->{}; //error
44 SAM s2 = param->{ Object local = null; }; //error
45 SAM s3 = field1->{ Object field_2 = null; }; //ok
46 }
48 void testParamInstance(Object local) {
49 SAM s1 = local->{}; //error
50 SAM s2 = param->{ Object local = null; }; //error
51 SAM s3 = field1->{ Object field_2 = null; }; //ok
52 }
54 static void testParamStatic(Object local) {
55 SAM s1 = local->{}; //error
56 SAM s2 = param->{ Object local = null; }; //error
57 SAM s3 = field1->{ Object field_2 = null; }; //ok
58 }
60 void testForInstance() {
61 for (int local = 0; local != 0 ; local++) {
62 SAM s1 = local->{}; //error
63 SAM s2 = param->{ Object local = null; }; //error
64 SAM s3 = field1->{ Object field_2 = null; }; //ok
65 }
66 }
68 static void testForStatic(Iterable<Object> elems) {
69 for (int local = 0; local != 0 ; local++) {
70 SAM s1 = local->{}; //error
71 SAM s2 = param->{ Object local = null; }; //error
72 SAM s3 = field1->{ Object field_2 = null; }; //ok
73 }
74 }
76 void testForEachInstance(Iterable<Object> elems) {
77 for (Object local : elems) {
78 SAM s1 = local->{}; //error
79 SAM s2 = param->{ Object local = null; }; //error
80 SAM s3 = field1->{ Object field_2 = null; }; //ok
81 }
82 }
84 static void testForEachStatic(Iterable<Object> elems) {
85 for (Object local : elems) {
86 SAM s1 = local->{}; //error
87 SAM s2 = param->{ Object local = null; }; //error
88 SAM s3 = field1->{ Object field_2 = null; }; //ok
89 }
90 }
92 void testCatchInstance() {
93 try { } catch (Throwable local) {
94 SAM s1 = local->{}; //error
95 SAM s2 = param->{ Object local = null; }; //error
96 SAM s3 = field1->{ Object field_2 = null; }; //ok
97 }
98 }
100 static void testCatchStatic(Iterable<Object> elems) {
101 try { } catch (Throwable local) {
102 SAM s1 = local->{}; //error
103 SAM s2 = param->{ Object local = null; }; //error
104 SAM s3 = field1->{ Object field_2 = null; }; //ok
105 }
106 }
108 void testTWRInstance(AutoCloseable res) {
109 try (AutoCloseable local = res) {
110 SAM s1 = local->{}; //error
111 SAM s2 = param->{ Object local = null; }; //error
112 SAM s3 = field1->{ Object field_2 = null; }; //ok
113 } finally { }
114 }
116 static void testTWRStatic(AutoCloseable res) {
117 try (AutoCloseable local = res) {
118 SAM s1 = local->{}; //error
119 SAM s2 = param->{ Object local = null; }; //error
120 SAM s3 = field1->{ Object field_2 = null; }; //ok
121 } finally { }
122 }
124 void testBlockLocalInstance() {
125 Object local = null;
126 {
127 SAM s1 = local->{}; //error
128 SAM s2 = param->{ Object local = null; }; //error
129 SAM s3 = field1->{ Object field_2 = null; }; //ok
130 }
131 }
133 static void testBlockLocalStatic() {
134 Object local = null;
135 {
136 SAM s1 = local->{}; //error
137 SAM s2 = param->{ Object local = null; }; //error
138 SAM s3 = field1->{ Object field_2 = null; }; //ok
139 }
140 }
142 void testSwitchLocalInstance(int i) {
143 switch (i) {
144 case 0: Object local = null;
145 default: {
146 SAM s1 = local->{}; //error
147 SAM s2 = param->{ Object local = null; }; //error
148 SAM s3 = field1->{ Object field_2 = null; }; //ok
149 }
150 }
151 }
153 static void testSwitchLocalStatic(int i) {
154 switch (i) {
155 case 0: Object local = null;
156 default: {
157 SAM s1 = local->{}; //error
158 SAM s2 = param->{ Object local = null; }; //error
159 SAM s3 = field1->{ Object field_2 = null; }; //ok
160 }
161 }
162 }
163 }