Let's compile the following code with ECJ compiler from Eclipse Mars.2 bundle:
import java.util.stream.*;
public class Test {
String test(Stream<?> s) {
return s.collect(Collector.of(() -> "", (a, t) -> {}, (a1, a2) -> a1));
}
}
The compilation command is the following:
$ java -jar org.eclipse.jdt.core_3.11.2.v20160128-0629.jar -8 -g Test.java
After the successful compilation let's check the resulting class file with javap -v -p Test.class
. The most interesting is the synthetic method generated for the (a, t) -> {}
lambda:
private static void lambda$1(java.lang.String, java.lang.Object);
descriptor: (Ljava/lang/String;Ljava/lang/Object;)V
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=2, args_size=2
0: return
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 a Ljava/lang/String;
0 1 1 t Ljava/lang/Object;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 1 1 t !*
I was quite surprised to see this !*
entry in LocalVariableTypeTable
. JVM specification covers LocalVariableTypeTable attribute and says:
The
constant_pool
entry at that index must contain aCONSTANT_Utf8_info
structure (§4.4.7) representing a field signature which encodes the type of a local variable in the source program (§4.7.9.1).
§4.7.9.1 defines a grammar for field signatures which, if I understand correctly, does not cover anything similar to !*
.
It should also be noted that neither javac compiler, nor older ECJ 3.10.x versions generate this LocalVariableTypeTable
entry. Is !*
some non-standard Eclipse extension or I'm missing something in JVM spec? Does this mean that ECJ does not conform to JVM spec? What !*
actually mean and are there any other similar strings which could appear in LocalVariableTypeTable
attribute?