我想知道编译器(ECJ,javac,或者你可以命名你喜欢的编译器)是否优化了匿名类,这些类不会添加或覆盖它的基类方法。
例如,对于看起来像这样的代码:
Snippet A:
Human h = new Human("John", 30);
h.setX(12.5);
h.setY(15.3);
//..
Eat(h);
我总是喜欢这种语法:
Snippet B:
Eat(new Human("John", 30){
{
setX(12.5);
setY(15.3);
//..
}
});
但是我明白,与vb.net中的WITH
关键字不同,这不仅仅是语法糖。我们告诉编译器要做的是创建一个Human的匿名子类,其构造函数由括号内的代码组成(这也是为什么我们不能在最终类中使用这种语法 - 糖的原因。)
现在的问题是我一直使用这种语法 - 糖 (例如在UI听众中覆盖onclick等),这就像我的编码风格/习惯之一。
因此问题:
编译器是否优化了这种语法? (即它意识到不需要生成匿名类, Snippet B 的性能与 Snippet A 相同)
如果(1)的答案是“否”,我想知道(由于这种编码风格,超出预期的丰富的匿名类)是一个明显的影响因此强烈建议对于未来的项目(平均移动设备的编码应用程序),我们应始终遵循 Snippet A 中的样式?
答案 0 :(得分:1)
编译器将创建一个单独的二进制类。
例如,如果你有
class Foo{
}
class Bar{
Foo otherFoo = new Foo(){
}
}
在bin / target目录中,您将有三个类
这里的匿名子类是Bar$1.class
答案 1 :(得分:1)
是的,它将(总是)生成一个匿名类(称为Human $ 1)。您可以通过检查输出的类文件来查看。你应该有一个Human.class和Human $ 1.class作为输出。
至于性能影响,将有两个类(更大,更多的VM工作),从一个到另一个的引用(因为匿名内部类将具有到外部类的链接)。我想这可能对性能有影响,但只是次要的。你必须测试它。
但是,这样做并不是特别惯用的java。惯用的方法是拥有另一个构造函数。