`

stream classdesc serialVersionUID = 1, local class serialVersionUID = 2

    博客分类:
  • Java
 
阅读更多

原创转载请注明出处:http://agilestyle.iteye.com/blog/2301301

 

先看一个简单的例子

package org.fool.test;

import java.io.Serializable;

public class User implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private long id;
	private String username;
	private String password;

	public User() {
	}

	public User(long id, String username, String password) {
		this.id = id;
		this.username = username;
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
	}

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

 这里先创建一个User对象,序列化UID为1L

package org.fool.test;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializableTest {
	public static void main(String[] args) throws Exception {
		ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("serial.txt"))));
		oos.writeObject(new User(1L, "hello", "world"));
		oos.close();
		
		ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("serial.txt"))));
		User user = (User) ois.readObject();
		System.out.println(user);
		ois.close();
	}
}

 接着使用IO进行读写,查看输出

User [id=1, username=hello, password=world]


本地工程下面生成了serial.txt文件,然后将User对象的序列化UID改为2L

public class User implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2L;

	private long id;
	private String username;
	private String password;
......

 同时注释掉原先的IO写操作,只进行读操作

public class SerializableTest {
	public static void main(String[] args) throws Exception {
		//ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(new File("serial.txt"))));
		//oos.writeObject(new User(1L, "hello", "world"));
		//oos.close();
		
		ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream(new File("serial.txt"))));
		User user = (User) ois.readObject();
		System.out.println(user);
		ois.close();
	}
}

 查看输出

Exception in thread "main" java.io.InvalidClassException: org.fool.test.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1623)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1518)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1774)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
	at org.fool.test.SerializableTest.main(SerializableTest.java:18)

Java通过一个名为UID(stream unique identifier)来控制,这个UID是隐式的,它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的。如果UID不一样的话,就无法实现反序列化了,并且将会得到InvalidClassException。这就是通常项目中版本升级会遇到的问题,很有可能缓存或者数据库的数据是以1L的版本写入,之后由于项目版本升级,UID变为了2L,在2L的基础上进行读操作,就会抛出这个异常,也就是序列化兼容性问题,解决的办法就是将UID版本统一,并且将原先缓存或数据库的数据清空,同时以当前最新的UID版本重新写入。

 

 

  • 大小: 7.1 KB
分享到:
评论

相关推荐

    java类中serialVersionUID的作用及其使用

    2. 自动生成serialVersionUID:如果没有显式定义serialVersionUID,Java序列化机制会根据Class自动生成一个serialVersionUID。 3. 使用IDE生成serialVersionUID:在Eclipse中,可以使用IDE生成serialVersionUID,...

    java序列化与反序列化

    为了防止这种情况,可以使用`ObjectStreamClass.lookup(Class)`检查类是否可信任,或者使用`ObjectInputStream.resolveClass(ClassDesc)`和`resolveProxyClass(String[])`来控制反序列化过程。 总结,Java序列化是...

    classdesc-开源

    1. **序列化与反序列化**:Classdesc可以方便地将对象的状态转换为二进制流,从而实现对象的持久化存储或网络传输。 2. **动态配置**:允许程序根据配置文件在运行时动态创建和配置对象,增强了系统的灵活性。 3. ...

    数据库(2)参考.pdf

    `UPDATE`语句用于修改已有数据,如`UPDATE classinfo SET classdesc='good' WHERE classid='3班'`将"3班"的班级描述更改为"good"。`DELETE FROM`则用于删除数据,`DELETE FROM studinfo WHERE studno='2011003'`将...

    Java安全漫谈 - 06.RMI篇(3)1

    对象类型可能是代理类(proxy class),如TC_OBJECT标识的TC_PROXYCLASSDESC,表示实现了两个接口:java.rmi.Remote和ICalc。接口名分别以UTF-8编码存储,表明该对象具备远程调用的能力。接着,类描述(classDesc)...

    3dsmax插件开发

    2. LibNumberClasses():返回插件包含的类数量。 3. LibClassDesc():根据索引返回特定的ClassDesc指针,用于创建插件对象。 4. LibVersion():确保插件与3dsmax版本兼容。 导出函数需要使用`__declspec(dllexport)...

    max 插件初始化

    1. **导出函数**: 所有3ds Max插件都需要一个导出函数,例如`FRExtension`或`FactoryClass`,这是3ds Max加载插件时调用的第一个函数。这个函数会告诉3ds Max关于插件的信息,如插件类型、版本和名称。 2. **类注册...

    3dsmax SDK 插件编程 (源码)

    源码分为"Day 1"和"Day 2"两个部分,可能代表了学习或开发过程中的两个阶段。让我们逐一解析这两个阶段可能包含的知识点: 1. **3ds Max SDK基础知识**:首先,你需要理解3ds Max SDK的基础概念,包括MaxScript、...

    3dsmax 2010 sdk

    1. **基础概念** - **插件开发**:3dsmax 2010 SDK支持C++和MAXScript两种方式开发插件,通过SDK中的API接口,开发者可以创建新的对象类型、修改现有对象的行为或实现新的功能。 - **MAXScript**:这是3ds Max的...

    CORBA客户端访问EJB

    | java.lang.Class | ::javax::rmi::CORBA::ClassDesc | 在某些情况下,例如java.lang.String,如果将其声明为final static,则可以直接映射为IDL中的wstring类型;而在其他情况下,它将被映射为值类型`CORBA::...

    jdk-12_osx-x64_bin.tar.gz

    有些类可以作为自己的符号引用(例如 String),而对于可链接常量,定义了一系列符号引用类型(ClassDesc、MethodTypeDesc、MethodHandleDesc 和 DynamicConstantDesc),它们包含描述这些常量的 nominal 信息。

    snippet辅助设计

    例如,定义一个名为`classdesc`的snippet,包括上述的文件头、类说明和函数说明模板。 4. 在XML文件中,使用`<Code>`标签定义代码区域,`<Expansion>`标签定义展开行为,`<Placeholder>`标签定义占位符。 5. 保存XML...

    JavadocExample_java_

    1. **Javadoc的基本结构** Javadoc注释可以包含多行文本,支持HTML标签,使得可以在注释中添加格式化文本、链接和其他元素。例如,你可以使用`<p>`标签创建段落,`<code>`标签高亮代码,`<a>`标签添加超链接等。 2...

    3DS Max 插件制作

    3dsMax通过识别继承自`ClassDesc2`类的实例来确定插件接口。此类实现了一系列与类ID、层次信息处理相关的函数,系统据此判断插件的有效性。 #### 2.3 插件调试技巧 调试插件时,需将工程属性设置为Hybrid模式,...

    minsky:系统动力学经济学建模软件

    明斯基动态流程系统程序可模拟经济流程(即复杂的系统动态)。 有关完整概述,请参见夹和文件概述的应用程序和DAG引擎概述的描述了Minsky .mky模型文件的架构... Emscripten classdesc描述符可在浏览器中支持Minsky。

Global site tag (gtag.js) - Google Analytics