最近,我偶然发现了以下java语法:
ArrayList<String> nodes = new ArrayList<String>(){{add("n1");add("n2");}};
起初,我认为这是一个语法错误,但令我惊讶的是,代码没有给出编译或运行时错误。
我有以下问题:
请指出相关文献。
答案 0 :(得分:2)
这会创建一个包含自定义initializer的匿名类(请参阅初始化实例成员):
通常,您可以使用代码在构造函数中初始化实例变量。使用构造函数初始化实例变量有两种选择:初始化块和最终方法。 实例变量的初始化程序块看起来就像静态初始化程序块,但没有静态关键字:
{
// whatever code is needed for initialization goes here
}
当你想要一个已包含成员的列表时,它很方便,但在编译时产生更多代码,因为匿名类实际上被编译为扩展ArrayList
的不同的(全局)类。
我最近阅读了与此事有关的this post:
要注意的第一点是Java运行时根本不了解内部类。无论内部类是命名还是匿名,使用烟雾和镜像过程将内部类转换为全局类。如果类具有名称,则编译器生成名称格式为[outer] $ [inner]的类文件 - $是Java中的合法标识符。对于内部类,生成的类文件只是编号。因此,当编译本文开头的Thread示例时,我们最终会得到一个名为Test $ 1.class的类文件。数字“1”表示这是Test类中定义的第一个匿名类。
答案 1 :(得分:0)
这是一个实例块,它是在构造时执行的,是一个匿名子类。
除非有充分的理由,否则不要这样做。喜欢:
List<String> nodes = Arrays.asList("n1", "n2");
或者如果你需要可变性:
List<String> nodes = new ArrayList(Arrays.asList("n1", "n2"));
因为匿名类保留了对它所声明的类的包含实例的引用,这可能导致内存泄漏。