zoukankan      html  css  js  c++  java
  • 注意由双大括号匿名类引起的serialVersionUID编译告警

    问题描述

    最近版本组织清理编译告警,其中有这么一条比较有意思,之前没见过,拿出来说一说

    serializable class anonymous com.demo.Main$1 has no definition of serialVersionUID

    编译告警指向了这段代码:

    private static List<String> defaultAttrList = new ArrayList<String>() {
        {
            add(ResourceConsts.RES_NAME);
            add(ResourceConsts.RES_TYPE);
            add(ResourceConsts.RES_IP);
            add(ResourceConsts.RES_VERSION);
        }
    };
    

    乍一看好像没什么问题,我用双大括号的方式定义并初始化了一个ArrayList,往里面塞了几个值,代码简洁易懂。

    但问题并没有看起来那么简单,原因就在双大括号

    探究

    双大括号的写法实际上创建了一个匿名类,我们将源文件编译后也会发现,生成了一个Main$1.class的文件,它就对应这个匿名类。反编译后的代码如下:

    class Main$1 extends ArrayList<String> {
        Main$1() {
            this.add("1");// 10
        }// 11
    }
    

    可以看到,我们创建了一个名为Main$1的匿名类,继承自ArrayList,而ArrayList的类定义如下:

    public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, Serializable {
        // ......
    }
    

    正是因为ArrayList实现了Serializable接口,所以Main$1也需要定义serialVersionUID

    解决方法

    既然是由于匿名类引起的编译告警,我们可以干掉匿名类,用静态域来初始化List,像下面这样即可消除告警:

    private static List<String> defaultAttrList = new ArrayList<>();
    static {
        defaultAttrList.add(ResourceConsts.RES_NAME);
        defaultAttrList.add(ResourceConsts.RES_TYPE);
        defaultAttrList.add(ResourceConsts.RES_IP);
        defaultAttrList.add(ResourceConsts.RES_VERSION);
    }
    

    参考资料

    1. 永远不要使用双花括号初始化实例,否则就会OOM!
  • 相关阅读:
    pymsql及事务
    MySQL表的操作
    MySQL操作
    epoll、mysql概念及简单操作
    IO模型
    面向对象4
    面向对象3
    面向对象2
    练习——网络编程2
    练习——网络编程
  • 原文地址:https://www.cnblogs.com/still-waters/p/13883992.html
Copyright © 2011-2022 走看看