java 中 ArrayList 声明中的奇怪语法
Strange syntax in ArrayList declaration in java
最近,我偶然发现了以下 java 语法:
ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}};
起初,我以为是语法错误,但令我惊讶的是,代码没有给出编译或运行时错误。
我有以下问题:
- 在Java中是否有此类声明的标准定义和文档?
- 编译这段代码会发生什么?
请指点相关文献。
这将创建一个带有自定义 initializer 的匿名 class(参见 初始化实例成员):
Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods.
Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
当你想要一个已经有成员的列表时,它很方便,但编译时会产生更多代码,因为匿名 class 实际上被编译为一个(全局)class 不同的扩展 ArrayList
.
我最近阅读了与此事相关的 this post:
The first point to note is that the Java runtime has no understanding of inner classes at all. Whether the inner class is named or anonymous, a smoke-and-mirrors procedure is used to convert the inner class to a global class. If the class has a name, then the compiler generates class files whose names have the format [outer]$[inner] — $ is a legal identifier in Java. For inner classes, the generated class files are simply numbered. So when the Thread example at the start of this article is compiled, we end up with a class file called Test.class. The number '1' indicates that this is the first anonymous class defined within the class Test.
这是一个实例块,在构建时执行,匿名子class。
除非有充分的理由,否则不要这样做。偏好:
List<String> nodes = Arrays.asList("n1", "n2");
或者如果您需要可变性:
List<String> nodes = new ArrayList(Arrays.asList("n1", "n2"));
因为匿名 class 保留对声明它的 class 的包含实例的引用,这可能导致内存泄漏。
最近,我偶然发现了以下 java 语法:
ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}};
起初,我以为是语法错误,但令我惊讶的是,代码没有给出编译或运行时错误。
我有以下问题:
- 在Java中是否有此类声明的标准定义和文档?
- 编译这段代码会发生什么?
请指点相关文献。
这将创建一个带有自定义 initializer 的匿名 class(参见 初始化实例成员):
Normally, you would put code to initialize an instance variable in a constructor. There are two alternatives to using a constructor to initialize instance variables: initializer blocks and final methods. Initializer blocks for instance variables look just like static initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
当你想要一个已经有成员的列表时,它很方便,但编译时会产生更多代码,因为匿名 class 实际上被编译为一个(全局)class 不同的扩展 ArrayList
.
我最近阅读了与此事相关的 this post:
The first point to note is that the Java runtime has no understanding of inner classes at all. Whether the inner class is named or anonymous, a smoke-and-mirrors procedure is used to convert the inner class to a global class. If the class has a name, then the compiler generates class files whose names have the format [outer]$[inner] — $ is a legal identifier in Java. For inner classes, the generated class files are simply numbered. So when the Thread example at the start of this article is compiled, we end up with a class file called Test.class. The number '1' indicates that this is the first anonymous class defined within the class Test.
这是一个实例块,在构建时执行,匿名子class。
除非有充分的理由,否则不要这样做。偏好:
List<String> nodes = Arrays.asList("n1", "n2");
或者如果您需要可变性:
List<String> nodes = new ArrayList(Arrays.asList("n1", "n2"));
因为匿名 class 保留对声明它的 class 的包含实例的引用,这可能导致内存泄漏。