技术标签: java基础
转自:https://www.cnblogs.com/xuxinstyle/p/11394358.html
如果您曾经实现过Serializable接口,则必须遇到此警告消息
The serializable class xxx does not declare a static final serialVersionUID field of type long
那么......什么是serialVersionUID?
在Java中,serialVersionUID类似于版本控制,确保序列化和反序列化的对象都使用兼容的类。
例如,如果一个对象保存在带有serialVersionUID=1L的文件(序列化)中,当我们将文件转换回一个对象(派生)时,我们必须使用相同的serialVersionUID=1L,否则抛出InvalidClassException
参考:https://mkyong.com/java-best-practices/understand-the-serialversionuid/
1. SerialVersionUID示例
上面的语句在开头有点难以理解(至少我做过),让我们开始一个例子来了解Serializable类如何使用SerialVersionUID来实现版本控制。
1.1 Address.java
serialVersionUID为1L的可序列化类。
import java.io.Serializable;
public class Address implements Serializable{
private static final long serialVersionUID = 1L;
String street;
String country;
public void setStreet(String street){
this.street = street;
}
public void setCountry(String country){
this.country = country;
}
public String getStreet(){
return this.street;
}
public String getCountry(){
return this.country;
}
@Override
public String toString() {
return new StringBuffer(" Street : ")
.append(this.street)
.append(" Country : ")
.append(this.country).toString();
}
}
1.2 WriteObject.java
将Address对象写入/序列化为文件的简单类 - “c:\\ address.ser”。
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class WriteObject{
public static void main (String args[]) {
Address address = new Address();
address.setStreet("wall street");
address.setCountry("united states");
try{
FileOutputStream fout = new FileOutputStream("c:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(address);
oos.close();
System.out.println("Done");
}catch(Exception ex){
ex.printStackTrace();
}
}
}
1.3 ReadObject.java
从文件中读取/反序列化Address对象的简单类 - “c:\\ address.ser”。
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class ReadObject{
public static void main (String args[]) {
Address address;
try{
FileInputStream fin = new FileInputStream("c:\\address.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
address = (Address) ois.readObject();
ois.close();
System.out.println(address);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
2.测试
让我们做一些测试来演示serialVersionUID的使用。
2.1相同的serialVersionUID
相同的serialVersionUID,在反序列化过程中没有问题
javac Address.java javac WriteObject.java javac ReadObject.java java WriteObject java ReadObject Street : wall street Country : united states
复制
2.2不同的serialVersionUID
在Address.java中,将serialVersionUID更改为2L(它是1L),然后再次编译它。
javac Address.java java ReadObject java.io.InvalidClassException: Address; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2 ... at ReadObject.main(ReadObject.java:14)
“ InvalidClassException”会引发,因为您使用serialVersionUID“1L”编写了一个序列化类,但尝试使用更新的序列化类serialVersionUID“2L”将其检索回来。
serialVersionUID必须在序列化和反序列化过程中匹配。
什么时候应该更新你的serialVersionUID?
如果使用对可序列化类的某些不兼容的Java类型更改更新序列化类,则必须更新serialVersionUID。
有关可序列化类的兼容和不兼容Java类型更改的详细信息,请参阅Java对象序列化规范。
3.默认的serialVersionUID有什么问题?
如果没有声明serialVersionUID,JVM将使用自己的算法生成默认的SerialVersionUID,您可以在此处检查算法。
默认的serialVersionUID计算对类详细信息非常敏感,可能因不同的JVM实现而异,并且在反序列化过程中会导致意外的InvalidClassExceptions。
3.1客户端/服务器环境
- 客户端在Windows中使用SUN的JVM。
- 服务器在Linux中使用JRockit。
客户端通过套接字向服务器发送带有默认生成的serialVersionUID(例如123L)的可序列化类,服务器可以在反序列化过程中生成不同的serialVersionUID(例如124L),并引发意外的InvalidClassExceptions。
3.2文件/数据库环境
- App#1在Windows中使用SUN的JVM。
- App#2在Linux中使用JRockit。
序列化允许保存到文件或数据库中。App#1默认生成serialVersionUID(例如123L)将可序列化类存储到数据库中,而App#2可能在反序列化过程中生成不同的serialVersionUID(例如124L),并引发意外的InvalidClassExceptions。
4.如何生成serialVersionUID
您可以使用JDK“ serialver”或Eclipse IDE自动生成serialVersionUID,详见详细信息。
结论
SUN强烈建议开发人员声明serialVersionUID以避免上面列出的不同JVM问题,但我建议您应该了解什么是序列化,serialVersionUID如何实现版本控制以及您的类需要使用序列化的原因。了解serialVersionUID概念优于任何推荐的盲目。
文章浏览阅读4.4w次,点赞17次,收藏7次。1.问题背景: 某些时候会接收到别人发给我们的xmind(一种思维导图)的文件,但苦于我们的电脑上没有下载Xmind软件,所以我们怎么快捷的查看该文件的内容呢?2.解决方案:Step 1: 我在网络上搜索了相关的解决方法,发现一个比较快捷的,因此推荐给大家,就是我们可以直接使用百度脑图 (https://naotu.baidu.com/)来直接打开xmind类型文件。 首先我们需要登录我们的百度账号进去,然后就进入到了以下界面:Step 2: 然后我们点击新建脑图,然后再直接点击这_xmind在线打开
文章浏览阅读480次。1、project路径名必须是纯英文。空格不知道能不能有,大家还请自己试试,这也是我自己出的问题。2、这必须是个project而不是单一的一个cpp文件。其实这已经隐含在1里面了3、本身没有打开编译器的-g标志。这个比较隐蔽,但是我试了试好像没有什么影响,大家要是1,2都试了不行可以再看看这个。具体方法:在Settings->Complier and debugger->Global complier settings->Complier settings->Complier f_codeblock断点不停
文章浏览阅读857次,点赞23次,收藏18次。范围for、new内存动态分配、nullptr
文章浏览阅读1.5k次。lightoj 1268 Unlucky Strings (矩阵快速幂+kmp DFA 好题)_unlucky string
文章浏览阅读425次。function () { alert("error");} //报错:匿名函数不能直接调用使用0x01(function () { alert("Success");})()//直接使用0x02var anonymous=function () { alert("success");}anonymous();//赋值调用传参0x01(function (m,n) { return m+n;})(10,20)//直接使用0x02var ano_js return anonymous()
文章浏览阅读897次。声明bug:由于此篇博客是在bindcolumnchange事件中做的值的改变处理,因此会出现当你选择时,没有点击确定,直接取消返回后,会发现选择框的值依然改变。造成原因:这一点就是由于在bindcolumnchange事件做的值改变处理造成。处理方法:如果需要确定后再改变值,请将bindcolumnchange事件中的处理操作放到bindchange事件中。效果图WXML..._小程序时间选择器颗粒度为分钟
文章浏览阅读4.6k次,点赞8次,收藏54次。前面的博客中链接1、前言已经给出Hadoop3.1.2和yarn的完整部署(但还不是高可用),此篇博客将给出Hadoop的高可用部署,以及HBase高可用,为之后应用数据层开发提供底层的BigTable支持。前面的文章,我们已经深入讨论的ZooKeeper这个中间件的原理以及分布式锁的实现,事实上zookeeper使用最广泛的场景是“选举”主从角色,Hadoop以及Hbase的高可用(主从架构..._hadoop集群做了ha,如何在两个nn上部署hbase
文章浏览阅读827次,点赞15次,收藏22次。1.背景介绍自动编码器(Autoencoders)和生成对抗网络(Generative Adversarial Networks,GANs)都是深度学习领域的重要算法,它们在图像生成、数据压缩、特征学习等方面都有着广泛的应用。然而,这两种算法虽然在应用场景和表现效果上有很大的不同,但它们的核心思想和算法原理却是相通的。本文将从以下几个方面进行阐述:背景介绍核心概念与联系核心算法原理和...
文章浏览阅读1.5w次,点赞10次,收藏98次。介绍CHI协议中的Cache Stashing操作和DVM操作_cache stashing
文章浏览阅读2.1k次。vscode 作为一款网红 IDE,其丰富的插件让人叹为观止,通过 vscode 提供的插件机制,我们几乎可以自定义 vscode 的所有细节。事实上很多 vscode 的核心功能也是通过插件实现的。本文我们将从以下三个方面详述 vscode 的插件机制:插件的基本结构插件执行环境插件的运行流程阅读本文后续内容,需要对 vscode 的插件开发有基本的了解。关于 vscode 的插件开发..._vscode插件体系的基本概念
文章浏览阅读278次。原文地址:https://medium.com/@devfire/how-to-become-a-devops-engineer-in-six-months-or-less-part-4-package-47677ca2f058原文作者:Igor Kantor翻译君:CODING 戴维奥普斯前情提要在这个系列的第一篇文章中,我们详细地介绍了 DevOps 相关的文化和基础技能;在第二..._devops项目集成go语言编译打包部署环境
文章浏览阅读600次。UbuntuCore 18.04 修改国内镜像源(Ubuntu Ports)工作中在全志 H3 ARM 架构上移植使用了 UbuntuCore 18.04 系统,其默认镜像源为国外源,更新缓慢。故修改使用国内中国科学技术大学的镜像源,具体修改方法如下:一、修改镜像源文件http://ports.ubuntu.com/ 为 http://mirrors.ustc.edu.cn/ubuntu-port..._ubuntu18 ports 国内源