serialversionuid(serialversionuid的作用)

更新时间:2023-03-01 10:44:03 阅读: 评论:0

rialVersionUID是什么?

rialVersionUID:意思是序列化的版本号。

【作用】一些java类中为什么需要重载 rialVersionUID 属性。在Java中,软件的兼容性是一个大问题,尤其在使用到对象串行性的时候,那么在某一个对象已经被串行化了,可是这个对象又被修改后重新部署了,那么在这种情况下, 用老软件来读取新文件格式虽然不是什么难事,但是有可能丢失一些信息。rialVersionUID来解决这些问题,新增的rialVersionUID必须定义成下面这种形式:static final long rialVersionUID=-2805284943658356093L;。其中数字后面加上的L表示这是一个long值。 通过这种方式来解决不同的版本之间的串行话问题。

【生成方式】它有两种显示的生成方式:
一个是默认的1L,比如:private static final long rialVersionUID = 1L;。
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:private static final long rialVersionUID = xxxxL。

rialVersionUID有什么作用?

rialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
有两种生成方式:
一个是默认的1L,比如:private static final long rialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
private static final long rialVersionUID = xxxxL;
当你一个类实现了Serializable接口,如果没有定义rialVersionUID,Eclip会提供这个
提示功能告诉你去定义 。在Eclip中点击类中warning的图标一下,Eclip就会
自动给定两种生成的方式。如果不想定义它,在Eclip的设置中也
可以把它关掉的,设置如下:
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems
将Serializable class without rialVersionUID的warning改成ignore即可。
如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入
rialVersionUID,Eclip都会给你warning提示,这个rialVersionUID为了让该类别
Serializable向后兼容。
如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Derialize时,就会出现Exception的,这样就会造成不兼容性的问题。
但当rialVersionUID相同时,它就会将不一样的field以type的预设值Derialize,可避开不兼容性问题。

如何生成rialversionuid

今天再看jdk的某些类的时候,突然看到了这个属性变量后面跟着很长的一串数字。以前也接触过这个东西。简单的就知道
为了jkd的版本和用这个类时的所用的jdk编译的版本的一个标识。用于反序列化的。
想用OjbectStreamClass。getSerialVersionID();这个方法打印出来看看也 老是报错;所以用了另一种方式:步骤如下:
1.先写个Test。java类 然后用javac Test编译这个类(这个类是你需要知道那个id的那个类)
public class Test implements java。io。rializable{
public static void main(String []args){}}
2.在jdk总,可以用JDK的bin目录下的rialver。exe工具产生这个SerialVersionUID
对于 Test。class 执行命令:rialver Test 即可在dos界面得到这个id了
rialVersionUID 用来表明类的不同版本间的兼容性

java类中rialversionuid 作用 是什么?举个例子说明.

类中影响Serialization进程的特征,两边的操作使用的类版本不同,但它们的 rialVersionUID 必须是一样的。它是用来识别两边的类是否兼容的,两边不同时不应该继续还原状态,而是应该停止下来,因为有人把事情搞错了。如果你的类没有实现 java.io.Serializable 或 java.io.Externalizable,这个字段则没有意义。


如果你没听说过 Java Serialization (序列化,有人书翻译成串行化),那去找些 rialization 介绍看看,下面说的第2段类结构变化时是中级水平的,理解 Java 的一些细节才能理解,多数情况下人们只提到第一种情况(类的结构没有变化时),也只需要第一种情况。


当Serialization两端(比如Socket两端)使用一个类的不同版本时,我们必须提供 rialVersionUID,它可以用JDK自带的 rialver 命令行来计算:

private static final long rialVersionUID = xxxx ;


如果类中出现了下面两个方法,那么将会被用到,否则使用默认的实现:

private void readObject(ObjectInputStream) throws IOException,ClassNotFoundException;

private void writeObject(ObjectOutputStream)throws IOException;

记住这里出现的方法和字段都是 private.


新版本中仅增加了字段或方法而没有改变旧版本中已有的东西时,我们只要保证两个版本中的 rialVersionUID 是一样的就行了.


具体样例可以看 JDK 源码中的像 ArrayList 这些类的代码的 readObject 和 writeObject 方法。


类的结构有些变化时,新版本对旧版本中某些东西进行了删减时, Field 的变化我们需要在readObject和writeObject方法中进行处理

ObjectOutputStream.PutField 类可达到这个目的

只是保证两个版本中的 rialVersionUID 一致是行不通的

类中必需两个常量:

private static final long rialVersionUID;

private static final ObjectStreamField[] rialPersistentFields


下面样例是当客户端和服务端使用的类的版本不同并且类的结构也改变了,比如:

对方使用的类Entry是:
publicclassEntry12...{
privateStringname,email;
privatestaticfinallongrialVersionUID=12L;
}
现在我们改变了类的设计了:
publicclassEntry12...{
privateEntryInternalbasic;
privatestaticfinallongrialVersionUID=12L;
privateclassEntryInternal{
privateStringname,email;
}
}


/*这是一段代码片段,我们假设新版本的类name&email两个字段进行了修改
*(这里我们放到一个内部类EntryInternal中),而旧版本中直接属于这个类.
*
*请注意这里的字段和方法的签名,它们都是private的或者是常量.
*/
publicclassEntry12implementsSerializable{
privateEntryInternalpair=newEntryInternal();

/*这是必要的,因为版本不同*/
privatestaticfinallongrialVersionUID=12L;

**这也是必要的,否则写putFields时会抛出异常.
*Thisfieldwillbeudby{@link#writeObject(ObjectOutputStream)},
*ifthisfieldismissing,follwingexceptionwillbethrewwheninvoke
*{@linkjava.io.ObjectOutputStream.PutField#put(String,)}:
*anexception‘java.lang.IllegalArgumentException:Nosuchobjectfield’willbethrew.
*/
privatestaticfinalObjectStreamField[]rialPersistentFields=newObjectStreamField[]{
newObjectStreamField("name",String.class),//
newObjectStreamField("email",String.class),//
};
/*我们在这里不是直接写出字段,而把要写出的字段包装起来,
我们按需交换字段,而不是直接读写pair这个字段.
*/
privatevoidreadObject(ObjectInputStreaminput)throwsIOException,ClassNotFoundException{
ObjectInputStream.GetFieldgetFields=input.readFields();

/*请注意:使用Serializable进行交换时不使用构造方法,所以这时pair还未初始化.*/
pair=newEntryInternal();

pair.name=(String)getFields.get("name",null);
pair.email=(String)getFields.get("email",null);
}

/*写出时跟读入时一样*/
privatevoidwriteObject(ObjectOutputStreamoutput)throwsIOException{
ObjectOutputStream.PutFieldputFields=output.putFields();

putFields.put("name",pair==null?null:pair.name);
putFields.put("email",pair==null?null:pair.email);

output.writeFields();
}

…..

}

自动生成 rialVersionUID 的设置(2021.1)

自动生成 rialVersionUID 的设置 (本配置2021.1版本配置)

(添加rialVersionUID 的时候,先选中对应的类名,然后按 alt+enter/(ctril+1) 快捷键)没有强调到位。

1:没有设置之前,选中对应的类名,然后按 alt+enter 快捷键 的情况如下所示

2:设置自动生成 rialVersionUID 的方式如下图所示,关键点已逐个标识(java下面)

3:设置之后,选中对应的类名【AppVersion】,然后按 alt+enter(ctril+1) 快捷键的情况如下

4:ok,打完收工


本文发布于:2023-02-28 19:52:00,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/zhishi/a/167763864372467.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:serialversionuid(serialversionuid的作用).doc

本文 PDF 下载地址:serialversionuid(serialversionuid的作用).pdf

相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 实用文体写作网旗下知识大全大全栏目是一个全百科类宝库! 优秀范文|法律文书|专利查询|