Java SerialVersionUID作用详解

问题1:Serializable是什么

首先,说说Serializable是实现java将内存中的类存储至硬盘中而使用的

一个类使用了Serializalbe接口,在序列化到文件时,会有一个SerialVersionUID。

这个东东是用于对类进行版本控制的。

首先看Person类清单:

=====

import  java.io.Serializable;

public  class  Person  implements  Serializable {

     //如果没有指定serialVersionUID,系统会自动生成一个
     private  static  final  long  serialVersionUID = 1L;
     private  String name;
     //添加这么一个成员变量
     private  String address;    //序列化后如果之前版本没有,就为null

     public  String getName() {
//      int a = 100;
//      for(int i=0;i<a;i++){
//          name+=i;
//      }
         return  name;
     }
     public  void  setName(String name) {
         this .name = name;
     }
}

===== 然后是测试类清单 =====

import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.FileOutputStream;
import  java.io.IOException;
import  java.io.ObjectInputStream;
import  java.io.ObjectOutputStream;

/**
  * if Object implements Serializable without Uid,
  * system will automatically give this object a uid by algorithm
  * @author v11
  * @date 2014年9月18日
  * @version 1.0
  */
public  class  WhySerialversionUID {

     public  static  void  objectToFile(Object obj,String fileName)  throws  Exception{
         ObjectOutputStream oo =  new  ObjectOutputStream( new  FileOutputStream(
                 fileName));
         oo.writeObject(obj);
         oo.close();
     }

     public  static  Object getObjectFromFile(String fileName)  throws  Exception {
         ObjectInputStream oi =  new  ObjectInputStream( new  FileInputStream(
                 fileName));
         Person crab_back = (Person) oi.readObject();
         oi.close();
         return  crab_back;
     }
     public  static  void  main(String[] args)  throws  Exception {
         String fileName =  "crab_file" ; //文件名

         // 这里是把对象序列化到文件
         Person crab =  new  Person();
         crab.setName( "Mr.Crab" );

         //储存到文件中
         //objectToFile(crab,fileName);

         // 这里是把对象序列化到文件,我们先注释掉,一会儿用
         Person crabBack = (Person) getObjectFromFile(fileName);
         //Dog crabBack = (Dog) getObjectFromFile(fileName);
         System.out.println( "Hi, My name is "  + crabBack.getName());

     }
}

=====

1.对于Person类中,将变量 address和SerialVersionUID注释掉,存储到文件,并读出。显示正常

2.将变量address还原,读取原来存储的文件,显示异常。抛出错误 InvalidClassException。

原因如下:

因为我们没有指定SerialVersionUID,因此系统自动生成了一个serialVersionUID(这个是根据类名,变量名,方法名)生成的

但是改动后的Person中变量名有变动,于是这个UID就不一样了,对于版本控制就无法读取。

所以,大家在很多代码里看到把UID设置为1L,就是Person代码中那样。

将Person代码UID设置为1L,再重复上述步骤,不报错。那么就意味着如果你选择将UID设置为1L,就是选择了兼容类的版本不一致。

PS:为什么说自动生成的 serialVersionUID是根据 类名,变量名,方法名,因为当你在原有的类的方法内进行添加内容,并不是对最后系统生成的UID造成影响,即不会抛出错误

问题2:所有类都设置为1L,是否有不良影响,不同类会不会冲突

public  class  Dog  implements  Serializable{

     private  static  final  long  serialVersionUID = 1L;
     private  String name;

     public  String getName() {
         return  name;
     }

     public  void  setName(String name) {
         this .name = name;
     }

}

新定义Dog类如上,将测试类代码中Dog的赋值注释去掉

 //Dog crabBack = (Dog) getObjectFromFile(fileName);

运行结果抛出错误:

Exception in thread "main" java.lang.ClassCastException: serializable.Person cannot be cast to serializable.Dog

说明serializable在不同类一间并不矛盾。

到此这篇关于Java SerialVersionUID作用详解的文章就介绍到这了,更多相关Java SerialVersionUID内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 序列化版本号serialVersionUID的作用_动力节点Java学院整理

    Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象. 序列化是Java中实现持久化存储的一种方法:为数据传输提供了线路级对象表示法. Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常. Eclipse中The

  • java类中serialVersionUID的作用及其使用

    实现Serializable接口的目的是为类可持久化,比如在网络传输或本地存储,为系统的分布和异构部署提供先决条件.若没有序列化,现在我们所熟悉的远程调用,对象数据库都不可能存在, serialVersionUID适用于java序列化机制.简单来说,JAVA序列化的机制是通过判断类的serialVersionUID来验证的版本一致的.在进行反序列化时,JVM会把传来的字节流中的serialVersionUID于本地相应实体类的serialVersionUID进行比较.如果相同说明是一致的,可以进

  • java序列化和serialVersionUID的使用方法实例

    java序列化和serialVersionUID的使用方法实例 1.序列化: 序列化可以将一个java对象以二进制流的方式在网络中传输并且可以被持久化到数据库.文件系统中,反序列化则是可以把之前持久化在数据库或文件系统中的二进制数据以流的方式读取出来重新构造成一个和之前相同内容的java对象.  2.序列化的作用: 第一种:用于将java对象状态储存起来,通常放到一个文件中,使下次需要用到的时候再读取到它之前的状态信息. 第二种:可以让java对象在网络中传输.  3.序列化的实现: 1).需要

  • 详解Java对象序列化为什么要使用SerialversionUID

    1.首先谈谈为什么要序列化对象 - 把对象转换为字节序列的过程称为对象的序列化. - 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器

  • 全面解释Java中的serialVersionUID

    serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性. 有两种生成方式:一个是默认的1L,比如:private static final long serialVersionUID = 1L;一个是根据类名.接口名.成员方法及属性等来生成一个64位的哈希字段,比如:private static final   long     serialVersionUID = xxxxL; 当你一个类实现了Serializable接口,如果没有定义s

  • Java SerialVersionUID作用详解

    问题1:Serializable是什么 首先,说说Serializable是实现java将内存中的类存储至硬盘中而使用的 一个类使用了Serializalbe接口,在序列化到文件时,会有一个SerialVersionUID. 这个东东是用于对类进行版本控制的. 首先看Person类清单: ===== import java.io.Serializable; public class Person implements Serializable { //如果没有指定serialVersionUID

  • Java中反射机制和作用详解

    前言 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象. 那么接下来大师就带你们了解一下反射是什么,为什么要学习反射? 下面我们首先通过一个实例来说明反射的好处: 方法1.不用反射技术,创建用户对象,调用sayHello方法 1.1 我们首先创建一个User类 package com.dashi; /** * Author:Java大师 * User对象,包含用户的id和姓名以及sayHello方法 */ public

  • java编程小白进阶包的作用详解

    目录 步骤 1  工具包里面有很多个工具类 步骤 2  StringUtil 步骤 3  目前的情况 步骤 4  CLASSPATH 步骤 5  具体配置 步骤 6  package 步骤 7  验证 步骤 8  亲自做一遍 步骤 9  为什么现在用Editplus运行报错了? 步骤 10  说白了 步骤 11  包的作用 包的作用,1是为了防止类和方法的重名,2是为了管理众多的java类. 步骤 1  工具包里面有很多个工具类 之前讲了打印数据的方法:System.out.println,写这

  • Android项目中实体类entity的作用详解

    估计很多入门安卓的朋友对entity很困惑,为什么要写实体类?有什么用?写来干什么? 对于实体类的理解我入门的时候也是困惑了好久,后面用多了才慢慢理解,这篇博客就当复习和笔记. Java中entity(实体类)的写法规范 在日常的Java项目开发中,entity(实体类)是必不可少的,它们一般都有很多的属性,并有相应的setter和getter方法.entity(实体类)的作用一般是和数据表做映射.所以快速写出规范的entity(实体类)是java开发中一项必不可少的技能. 在项目中写实体类一般

  • Java 多线程实例详解(三)

    本文主要接着前面多线程的两篇文章总结Java多线程中的线程安全问题. 一.一个典型的Java线程安全例子 public class ThreadTest { public static void main(String[] args) { Account account = new Account("123456", 1000); DrawMoneyRunnable drawMoneyRunnable = new DrawMoneyRunnable(account, 700); Thr

  • java对象拷贝详解及实例

    java对象拷贝详解及实例 Java赋值是复制对象引用,如果我们想要得到一个对象的副本,使用赋值操作是无法达到目的的: @Test public void testassign(){ Person p1=new Person(); p1.setAge(31); p1.setName("Peter"); Person p2=p1; System.out.println(p1==p2);//true } 如果创建一个对象的新的副本,也就是说他们的初始状态完全一样,但以后可以改变各自的状态,

  • Java 多线程实例详解(二)

    本文承接上一篇文章<Java多线程实例详解(一)>. 四.Java多线程的阻塞状态与线程控制 上文已经提到Java阻塞的几种具体类型.下面分别看下引起Java线程阻塞的主要方法. 1.join() join -- 让一个线程等待另一个线程完成才继续执行.如A线程线程执行体中调用B线程的join()方法,则A线程被阻塞,知道B线程执行完为止,A才能得以继续执行. public class ThreadTest { public static void main(String[] args) {

  • Java分层概念详解

    service是业务层 action层即作为控制器 DAO (Data Access Object) 数据访问 1.JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分?(下面所描述的service层就是biz) 首先这是现在最基本的分层方式,结合了SSH架构.modle层就是对应的数据库表的实体类. Dao层是使用了Hibernate连接数据库.操作数据库(增删改查). Service(biz)层:引用对应的Dao数据库操作,在这里可以编写自己需要的代码(比如简

  • Java 阻塞队列详解及简单使用

     Java 阻塞队列详解 概要: 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全"传输"数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 认识BlockingQueue阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示: 从上图我们可以很清楚看到,通过一个共享的队列,

  • Java 线程优先级详解及实例

    Java 线程优先级详解及实例 操作系统基本采用时分的调度运行线程,操作系统会分出一个个时间片,线程会被分配到若干个时间片,当线程的时间片用完了就会发生线程调度,并且等待着下次调度,线程被分配到的时间片多少也就决定了线程使用处理器资源的多少,而线程优先级就是决定线程能够分配多少处理器资源的线程属性. 在Java多线程中,通过一个整形变量priority来控制优先级,优先级的范围从1-10.默认是5,优先级越高越好. public class Priority { public static vo

随机推荐