Strange syntax in ArrayList declaration in java

I recently came across the following java syntax:

ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}}; 

At first I thought it was a syntax error, but, to my surprise, the code did not give a compilation or runtime error.

I have the following questions:

  • Is there a standard definition and documentation for such a declaration in Java?
  • What happens when compiling this code?

Please provide me with relevant literature.

+5
source share
2 answers

This creates an anonymous class with a custom initializer (see Initializing Member Instances ):

Usually you add code to initialize an instance variable in the constructor. There are two alternatives to using the constructor to initialize instance variables: initialization blocks and final methods. Initializer blocks for instance variables look the same as static initializer blocks, but without a static keyword:

 { // whatever code is needed for initialization goes here } 

It is compelling when you need a list with existing members, but when compiling, more code is generated because the anonymous class is actually compiled into a (global) class other than ArrayList .

I recently read this post that is relevant:

The first thing to note is that the Java runtime does not understand inner classes at all. Regardless of whether the inner class is called or anonymous, the smoke and mirror procedure is used to transform the inner class into a global class. If the class has a name, then the compiler generates class files whose names have the format [external] $ [internal] - $, is the legal identifier in Java. For inner classes, the generated class files are simply numbered. Therefore, when the Thread example at the beginning of this article is compiled, we get a file of class Test $ 1.class. The number "1" indicates that this is the first anonymous class defined in the Test class.

+2
source

This is the instance block that is executed when constructing the anonymous subclass.

If there is no good reason, do not do this. Prefer:

 List<String> nodes = Arrays.asList("n1", "n2"); 

Or if you need volatility:

 List<String> nodes = new ArrayList(Arrays.asList("n1", "n2")); 

Because the anonymous class maintains a reference to the containing instance of the class that it declared, which could lead to memory leaks.

0
source

All Articles