Java 编译器是否优化不添加/重写方法的匿名类?
我想知道编译器(ECJ、javac或您最喜欢的编译器)是否优化了匿名类,这些匿名类不会添加或重写基类的方法 例如,对于如下所示的代码: 片段A: 我总是更喜欢语法: 片段B: 然而,我明白,与vb.net中的Java 编译器是否优化不添加/重写方法的匿名类?,java,android,coding-style,Java,Android,Coding Style,我想知道编译器(ECJ、javac或您最喜欢的编译器)是否优化了匿名类,这些匿名类不会添加或重写基类的方法 例如,对于如下所示的代码: 片段A: 我总是更喜欢语法: 片段B: 然而,我明白,与vb.net中的WITH关键字不同,这不仅仅是语法上的糖分。我们告诉编译器要做的是创建一个匿名的Human子类,其构造函数由大括号中的代码组成(这也是为什么我们不能对最终类使用这种语法) 现在的问题是,我一直在使用这种语法(比如在UI监听器中重写onclick等),这就像我的一种编码风格/习惯 因此,问题是
WITH
关键字不同,这不仅仅是语法上的糖分。我们告诉编译器要做的是创建一个匿名的Human子类,其构造函数由大括号中的代码组成(这也是为什么我们不能对最终类使用这种语法)
现在的问题是,我一直在使用这种语法(比如在UI监听器中重写onclick等),这就像我的一种编码风格/习惯
因此,问题是:
编译器将创建一个单独的二进制类 例如,如果你有
class Foo{
}
class Bar{
Foo otherFoo = new Foo(){
}
}
在bin/target目录中,您将有三个类
- 酒吧
- 一美元一班
- Foo.class
然而,这样做并不是java特有的习惯用法。惯用的方法是使用另一个构造函数。不幸的是,我不知道编译器将如何处理它。但是你可以自己编写一个循环,多次同时执行这两种方法,并进行测量,以了解这两种方法的性能影响。@Tim是的,但唯一的问题是,像这样做测试根本不准确。例如,在真实的应用程序中,这种代码不会在代码的某一部分中循环运行,而是在整个代码中从应用程序生命周期的开始到应用程序生命周期的结束都以位和块的形式运行(这类似于我们使用
if
和else
语句,它们是整个代码的一部分,而不是像循环中那样使用say)请注意:您没有定义构造函数,而是定义了一个初始值设定项块。这些块是在构造函数之前执行的!因此,您不能依赖其他字段是否已经使用这种方法创建了。我一直在努力解决这一问题,并且经常使用类似的类,但最近我选择了返回this
ins的setter代替了void
,这样你就可以把它们或一个构建器模式链接起来;
Eat(new Human("John", 30){
{
setX(12.5);
setY(15.3);
//..
}
});
class Foo{
}
class Bar{
Foo otherFoo = new Foo(){
}
}