最近,我偶然发现了以下Java语法:
ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}};
起初,我以为这是语法错误,但令我惊讶的是,代码在编译和运行时都没有出现错误。
我有以下问题:
- Java中是否有关于此声明的标准定义和文档?
- 当这段代码被编译时会发生什么?
请指向相关文献。
这将创建一个带有自定义初始化器(请参见初始化实例成员)的匿名类:
通常情况下,您会在构造函数中放置代码以初始化实例变量。有两种替代方法可以使用来初始化实例变量:初始化块和final方法。 实例变量的初始化块看起来就像静态初始化块,但没有static关键字:
{
// whatever code is needed for initialization goes here
}
当您需要一个已经包含成员的列表时,这很方便,但编译时会产生更多的代码,因为匿名类实际上被编译为一个(全局)类,该类扩展了ArrayList
。
我最近读到了这篇文章,与此相关:
首先要注意的是,Java运行时根本不理解内部类。无论内部类是命名的还是匿名的,都使用烟幕和镜子的程序将内部类转换为全局类。如果该类有名称,则编译器生成类文件,其名称的格式为[outer]$[inner]——$是Java中的合法标识符。对于内部类,生成的类文件仅仅是编号。因此,当在本文开头的线程示例被编译时,我们得到一个名为Test$1.class的类文件。数字'1'表示这是在类Test中定义的第一个匿名类。
这是一个匿名子类的实例块,在构造时执行。
除非有充分的理由,否则不要这样做。请使用:
List<String> nodes = Arrays.asList("n1", "n2");
或者如果您需要可变性:
List<String> nodes = new ArrayList(Arrays.asList("n1", "n2"));