Java_Magazine_NovemberDecember_2018

(singke) #1

46


//java at present/


In this code example, your StringIterator class is a private class, so only the StringIterable
class should be able to access it. Also note that StringIterator has access to the private string
field (marked by comments “1” and “2” in the preceding example) of the StringIterator
class. This combination of classes nested within a single source file (StringIterable and
StringIterator) is called a nest. Each of the classes individually is called a nestmate. It’s worth
noting that the concept of a nest applies only to classes syntactically nested within each other.
It doesn’t apply to different classes within the same source file.
What problem do nests solve? The historical problem with nests in Java is that their imple-
mentation damages encapsulation, confuses tooling by misrepresenting the nest, and bloats the
size of class files by generating extra methods.
If you decompile the generated bytecode for the previous example by using javap on Java
10 or earlier versions, you can see how nests are implemented historically. The StringIterator
class file is generated with the name StringIterable$StringIterator, indicating that it’s within
the StringIterable class. To access the private string field of StringIterable that its next() and
hasNext() methods use, StringIterator takes a constructor parameter with the StringIterable
object as a parameter:

StringIterable$StringIterator(StringIterable, StringIterable$1);

It also has an internal field that holds a reference to the StringIterable object:

final StringIterable this$0;

So far, so good. The problem comes when you want to read from the private string field. The
code within StringIterator can’t just refer to this$0.string, because string is a private field and
it lives in another class. To work around this problem, javac generates what is formally called a
synthetic accessor or bridge method, which is a bit of a hack:
Free download pdf