匿名内部类的效率分析
java中类实例的创建与销毁是比较耗时的。
今天搬砖时突然想到匿名内部类的实例创建,是调用一次创建一次吗,jvm会有优化吗?遂写了的测试类自己研究了下。
匿名内部类普通的写法:
services.addListener(new SimpleListener() {
@Override
void onMessage(){
do.sth
}
});
实际上,jvm在编译时会帮你把这个匿名内部类搞出来,但是这种写法在运行时,每执行一次这一行,就有一个该匿名内部类的实例被new出来。
所以,改成单例的写法更好一些:
private Listener listener = new SimpleListener() {
@Override
void onMessage(){
// do sth
}
};
....
services.addListener(listener);
在jdk8中,还有lambda的写法
services.addListener( ()-> do.sth );
lambda写法不会再有匿名内部类的产生,jvm会直接处理成内部代码的运行,也就没有了类实例的创建与销毁。
总之,推荐直接使用lambda写法,代码简洁的同时,运行效率也会更高。
测试代码:
private void print(Function f) {
f.apply("abc");
}
private Function function = new Function() {
@Override
public Object apply(Object o) {
System.out.println(toString());
return "";
}
};
@Test
public void test33() {
print(e -> {
System.out.println(toString());
return "";
});
print(e -> {
System.out.println(toString());
return "";
});
print(function);
print(function);
print(new Function() {
@Override
public Object apply(Object o) {
System.out.println(toString());
return "";
}
});
print(new Function() {
@Override
public Object apply(Object o) {
System.out.println(toString());
return "";
}
});
}
输出
TestController@6e6f2380
TestController@6e6f2380
TestController$1@2e8c1c9b
TestController$1@2e8c1c9b
TestController$2@53fe15ff
TestController$3@449a4f23
从输出结果上来看,lambda写法确实没有了内部类的产生
Stack Overflow上也有讨论二者效率的帖子:https://stackoverflow.com/questions/22637900/java8-lambdas-vs-anonymous-classes