@SuppressWarnings(“串行”)

2022-09-02 19:39:28

我有一个问题,因为我有点困惑(或者也许我没有注意到一些明显的东西)。假设我有一些源代码,其中包含许多类,这些类包含大量定义如下的静态字段:

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));
        }
    };

}

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

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

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

编辑:

我的类都没有实现可序列化接口(或者没有一个超类)。Eclipse也带着它的警告指向了这里。为什么它没有检测到它是静态场?HashMap<String, Byte>


答案 1

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

一种可能的解决方案是简单地避免使用带有初始值设定项样式的匿名子类,然后执行以下操作:

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));
}

在大多数情况下,结果几乎相同,并且您的代码中没有匿名类。


答案 2

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

错误消息和类中有一个最终的静态成员变量的事实(至少,这就是我如何解释你的描述)彼此没有任何关系。

你的类实现了接口,或者你的类的一个超类做到了这一点。因此,编译器会注意到您的类是可序列化的。可序列化的类应具有一个名为的静态 final 字段,该字段用于在序列化类的实例时进行版本控制。SerializableserialVersionUID

使用注释会使编译器对缺少的 .所以,是的,你可以用它来摆脱警告消息,但更好的解决方案是让你的类不实现(直接或间接地),如果它不打算被序列化。@SuppressWarnings("serial")serialVersionUIDSerializable