关于The serializable class does not declare a static final serialVersionUID field of type long
来源:互联网 发布:淘宝专卖店与专营店 编辑:程序博客网 时间:2024/05/22 04:48
当我们需要在Intent中传类时,我们会想起Serializable和Parcelable。当我们需要将类写入文件时,会想起Serializable。
这里我们讲下Serializable,使用它只需实现Serializable接口即可,但是在此时往往会提示”The serializable class does not declare a static final serialVersionUID field of type long”。这篇文章讲的主要是如何解决以及为什么会出现。
知其缘由
上面我们所说的两种用途涉及到类的序列化与反序列化,经常用来做版本控制。在这个过程中,JVM会比较字节流中的serialVersionUID 与本地类的serialVersionUID是否一致。如果不一致,会报InvalidClassException的异常。
定义形式如下:
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
我们可以书写下下面的测试样例。
实体类:
package serialVersionUID;import java.io.Serializable;public class User implements Serializable { private static final long serialVersionUID = -8003021310975257817L; public String name; public String address; public int userId; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } public String getName() { return this.name; } public String getAddress() { return this.address; } @Override public String toString() { return name + ":" + address + ":" + userId; }}
写入文件:
package serialVersionUID;import java.io.FileOutputStream;import java.io.ObjectOutputStream;public class WriteObject { public static void main(String[] argc) { User user = new User(); user.setName("jerry"); user.setAddress("dont want to tell u"); try { FileOutputStream fos = new FileOutputStream("D:\\Users\\LINHAIYANG\\Desktop\\java_test\\serialVersionUID\\user.jer"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(user); oos.close(); System.out.println("done"); } catch (Exception e) { e.printStackTrace(); } }}
读取实体:
package serialVersionUID;import java.io.FileInputStream;import java.io.ObjectInputStream;public class ReadObject { public static void main(String[] argc) { User user = null; try { FileInputStream fis = new FileInputStream("D:\\Users\\LINHAIYANG\\Desktop\\java_test\\serialVersionUID\\user.jer"); ObjectInputStream ois = new ObjectInputStream(fis); user = (User) ois.readObject(); ois.close(); System.out.println(user); } catch (Exception e) { e.printStackTrace(); } }}
根据上面的例子,当我们将类写入文件后,修改实体类的serialVersionUID时,再去读取实体,就会出现UID不一致的情况,报InvalidClassException的异常。
如果不定义
上面是因为我们手动修改了serialVersionUID导致的异常,如果我们使用Serializable不定义这个UID,会怎么样?
如果我们不定义UID,JVM会自动的生成UID,而生成方式与许多东西有关,例如JVM版本、文件存储方式(例如Windows与Ubuntu)有关、类属性方法等有关。
由于不方便测试JVM版本、文件存储方式对UID的影响,这里只测试类属性方法对UID的影响。使用如下代码获取类的UID:
ObjectStreamClass osc = ObjectStreamClass.lookup(User.class);System.out.print(osc.getSerialVersionUID());
根据这段代码在我的电脑下测试如下:
初始UID: -4269709306655343749
增加空格UID: -4269709306655343749
增加属性UID: -2183236014181697252
public int a;
增加方法UID: 7125364192856802935
public void a() {}
这里我们可以看到,增加属性和方法会对UID造成影响。因此,如果我们不定义UID的话,随着代码迭代,实体难免会修改属性或者方法。这样的话,以前写入文件的读取时就会产生异常。
同理的,JVM版本和文件存储方式也会对UID造成影响。
因此,建议在每个实体类都定义一个UID,以免产生问题。
如何定义
定义serialVersionUID有两种方式:
一是默认的1L,比如:
private static final long serialVersionUID = 1L;
二是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,这个编译器可以帮我们生成,比如:
private static final long serialVersionUID = xxxxL;
这两种方法根据文档来说没什么区别。当新版本需要兼容旧版本时,UID应保持不变,否则应该修改UID。
参考
- serialVersionUID计算方法
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100 - 好的介绍文章
http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/ - 官方文档
http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html
- 关于The serializable class does not declare a static final serialVersionUID field of type long
- The serializable class XXX does not declare a static final serialVersionUID field of type long
- the serializable class XXX does not declare a static final serialVersionUID field of type long
- The serializable class XXX does not declare a static final serialVersionUID field of type long
- The serializable class XXX does not declare a static final serialVersionUID field of type long
- The serializable class Proname does not declare a static final serialVersionUID field of type long
- The serializable class Client does not declare a static final serialVersionUID field of type long
- The serializable class Myplayer does not declare a static final serialVersionUID field of type long
- (转)关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 原创 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于“The serializable class XXX does not declare a static final serialVersionUID field of type long” 错
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class XXX does not declare a static final serialVersionUID field of type long的警告
- 关于The serializable class UsersServlet does not declare a static final serialVersionUID field of type
- 关于"the serializable class XXXXXXXX does not declare a static final seriaVersionUID field of type long"
- 马戏团(动态规划)---搜狐2016研发工程师编程题
- C++ 类的静态成员详细讲解
- redis 下key的过期时间详解 :expire
- js 生成随机字符串
- Properties 读取配置文件
- 关于The serializable class does not declare a static final serialVersionUID field of type long
- Hadoop(二)WordCount
- Protocol Buffers学习小记-基于servlet的http RPC实现
- 学习笔记7——在CentOS中修改中文字符集
- IntelliJ IDEA字体等配色方案设置
- java jdk1.7版本的LinkedList底层原理解析
- Activity绑定自定义视图
- Eclipse 出现none applicable问题
- oracle