Java_Magazine_NovemberDecember_2018

(singke) #1

47


//java at present/


static java.lang.String access$100(StringIterable);
Code:
0: aload_0
1: getfield #1 // Field string:Ljava/lang/String;
4: areturn

This access$100 method exists only to expose the private field string to the outside world. That
breaks encapsulation, because other classes can call this method via reflection, effectively turn-
ing a private field into a package-scoped field. An ACC_SYNTHETIC flag is set for this method to
indicate that it’s synthetic, that is, it’s
generated by javac. This compilation
strategy also introduces an asymmetry
between source code and reflection code
because in source code, you can read out
the private string field, but you can’t do
the same with reflection without using
the setAccessible() method.
The reason for this bridge method is that StringIterable and StringIterable$StringIterator
were different classes in this compilation approach. The JVM didn’t know about the relation-
ship between them and, thus, didn’t know what the access rules were between the two classes.
As a result, the bridge method was generated to expose the private field from where it needs to
be accessed.
If you compiled the same source code with Java 11, this method would disappear. That’s
because the concept of a nest and nestmates is being explicitly introduced to the JVM, which
enables reflection to work, smaller class files, and proper encapsulation. The private this$0 field
remains, however.
There is also arguably a performance improvement in these situations because under the
old compilation scheme, every access of a supposedly private field from a nestmate would need
to go through these bridge methods. Now, sometimes the JIT compiler may optimize away this

From Java 11 onward, the semantics at
the bytecode level are much closer to the source
code level when nested classes are compiled.
Free download pdf