匿名内部类的效率分析

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

posted @ 2019-10-23 18:14  ACBingo  阅读(912)  评论(0编辑  收藏  举报