@SuppressWarnings( "串行")

Luk*_*asz 18 java serialization suppress-warnings

我有一个问题,因为我有点困惑(或者我可能没注意到一些明显的东西).假设我有一些包含很多类的源代码,这些类包含大量像这样定义的静态字段:

public final class ConverterTYPE  {
    private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>() {
        {
            put("A", new Byte((byte)12));
            put("B", new Byte((byte)13));
        }
    };

}
Run Code Online (Sandbox Code Playgroud)

众所周知,静态字段不会被序列化.

但是,Java(和Eclipse)抱怨"可序列化类没有声明类型为long的静态最终serialVersionUID字段".为什么他们不能注意到静态不会被序列化?

接下来的问题是:用这个问题@SuppressWarnings("serial")摆脱所有这些警告是否是正确的解决方案?

编辑:

我的类都没有实现Serializable接口(或者没有超类).Eclipse正在指出HashMap<String, Byte>它的警告.为什么不检测到它是静态场?

Aff*_*ffe 23

仅仅因为该字段可能没有被序列化并不意味着它引用的东西永远不会被序列化!有人/其他东西可以获得对该映射的引用并尝试直接序列化它,或者将其用作可序列化类中的实例成员等.我看到它是私有的,但确保它永远不会在当前类之外访问或设置为实例成员超出了编译器的范围(无论如何都不可能反射).

一种可能的解决方案是简单地避免将匿名子类与初始化器样式放在一起并执行此操作:

private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>();

static {  
  STRING_MAP.put("A", new Byte((byte)12));
  STRING_MAP.put("B", new Byte((byte)13));
}
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,结果几乎相同,并且您的代码不会使用匿名类.

  • 我要补充说,在十个如此静态初始化的集合中,有九个是不变的。在这种情况下,您可以使用Google Collections库中一个不错的ImmutableMap类:“ ImmutableMap.of(” A“,(byte)12,” B“,(byte)13);`。还有一个`ImmutableMap。&lt;K,V&gt; builder()`,对于&gt; 5个元素是必需的。 (4认同)

Jes*_*per 20

但是,Java(和Eclipse)抱怨"可序列化类没有声明类型为long的静态最终serialVersionUID字段".为什么他们不能注意到静态不会被序列化?

错误消息以及您在类中有最终静态成员变量的事实(至少,我是如何解释您的描述)彼此之间没有任何关系.

您的类实现了接口Serializable,或者您的类的一个超类实现了该接口.因此编译器注意到您的类是可序列化的.可序列化的类应该有一个静态的final final字段serialVersionUID,当你序列化类的实例时,它会用于版本控制.

使用注释@SuppressWarnings("serial")会使编译器关闭缺失serialVersionUID.所以,是的,您可以使用它来消除警告消息,但更好的解决方案是让您的类不实现Serializable(直接或间接),如果它不是要序列化.

  • 哦等等,看起来你正在使用双支撑初始化(一个丑陋的技巧,恕我直言).注意`HashMap`实现`Serializable`,你的`HashMap`的匿名子类没有`serialVersionUID`.lweller在他的回答中显示如何将`serialVersionUID`添加到您的匿名子类. (9认同)