温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java的Serializable接口怎么使用

发布时间:2021-11-24 16:24:10 来源:亿速云 阅读:471 作者:iii 栏目:大数据

这篇文章主要介绍“Java的Serializable接口怎么使用”,在日常操作中,相信很多人在Java的Serializable接口怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java的Serializable接口怎么使用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、Serializable:序列化

1、Serializable位于java.io包中,用于实现Java类的序列化操作而提供的一个语义级别的接口。没有任何方法或者字段,只是用于标识可序列化的语义。

2、如类中的有些字段不想序列化,可用关键字:transient修饰。

3、序列化可通过ObjectOutputStream实现,反序列化可通过ObjectInputStream实现。

4、自定义序列化实现接口:Externalizable

5、序列化作用:用于网络传输(RPC远程调用); 将对象保存到磁盘(tomcat的钝化和活化)

6、使用建议:实现序列化接口,请增加:

private static final long serialVersionUID = 1L;

7、可直接通过序列化字节流使用

// 将对象本身序列化到字节流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

ObjectOutputStream objectOutputStream =

new ObjectOutputStream( byteArrayOutputStream );

objectOutputStream.writeObject( this );

// 再将字节流通过反序列化方式得到对象副本
ObjectInputStream objectInputStream =

new ObjectInputStream( new ByteArrayInputStream( byteArrayOutputStream.toByteArray() ) );

Object object = objectInputStream.readObject();

8、可通过java命令:serialver [-classpath classpath] [-show] [classname...] 查看类的序列化值

The -classpath option specifies where to look for the classes (in directories or jar files, separated by semicolon marks ;).

The -show option displays a simple user interface that allows the user to enter a full class name and then press Enter key or click Show button to display the serialVersionUID number.

示例:

//win+R打开cmd输入以下命令:

serialver -classpath E:\j2se-example\target\classes net.liuzd.j2se.example.copy.MyDong

Java的Serializable接口怎么使用

二、例子

1、测试类

1.1 代码示例
 

package net.liuzd.j2se.example.copy;

import java.io.*;

public class DongSerializableTest {

static String fileName = "dong.ser";

public static void main(String[] args) throws Exception {

Dong dong = new Dong();

dong.setName("杨过");

dong.setAge(19);

//

ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(fileName));

outputStream.writeObject(dong);

outputStream.close();

//

ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName));

Dong readDong = (Dong) inputStream.readObject();

System.out.println(readDong);

}

}


class Dong implements Serializable {

private String name;

private int age;

public Dong() {

}

public String getName() {

return name;
}

public void setName(String name) {

this.name = name;
}
public int getAge() {

return age;
}
public void setAge(int age) {

this.age = age;
}

@Override

public String toString() {

return "Dong{" +

"name='" + name + '\'' +

", age=" + age +

'}';

}

}

1.2 运行后,成功打印出结果: Dong{name='杨过', age=19}

2、测试类再增加一个属性

2.1 测试类再增加一个属性:sex及对应的get,set方法,重写toString()方法。

private int sex;

public int getSex() {

   return sex;

}

public void setSex(int sex) {

  this.sex = sex;

}


@Override

public String toString() {

return "Dong{" +

"name='" + name + '\'' +

", age=" + age +

", sex=" + sex +

'}';

}

2.2 直接运行方法:

ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName));

Dong readDong = (Dong) inputStream.readObject();

System.out.println(readDong);

2.3 发现报错了:

Exception in thread "main" java.io.InvalidClassException: net.liuzd.j2se.example.copy.Dong; local class incompatible: stream classdesc serialVersionUID = 2001103299326914393, local class serialVersionUID = 1180199239641161346

at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)

at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1963)

at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1829)

at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2120)

at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:482)

at java.io.ObjectInputStream.readObject(ObjectInputStream.java:440)

at net.liuzd.j2se.example.copy.DongSerializableTest.main(DongSerializableTest.java:20)

2.4 发现问题:

2.4.1、我们没有指定serialVersionUID,JDK8自动帮我们生成了一个

2.4.2、发现二个serialVersionUID不一致,才导致了运行错误。

2.5 查看接口:serializable的文档

2.5.1 明确指出需要我们显式声明为:private static final long serialVersionUID,这个对继承成员无用。

2.5.2 默认的serialVersionUID值对类细节高度敏感,这些细节可能因编译器而异实现,并因此可能导致意外的结果:InvalidClassException

2.5.3 其中的一段文档注释:

If a serializable class does not explicitly declare a serialVersionUID, then

the serialization runtime will calculate a default serialVersionUID value

for that class based on various aspects of the class, as described in the

Java(TM) Object Serialization Specification. However, it is <em>strongly

recommended</em> that all serializable classes explicitly declare

serialVersionUID values, since the default serialVersionUID computation is

highly sensitive to class details that may vary depending on compiler

implementations, and can thus result in unexpected

<code>InvalidClassException</code>s during deserialization. Therefore, to

guarantee a consistent serialVersionUID value across different java compiler

implementations, a serializable class must declare an explicit

serialVersionUID value. It is also strongly advised that explicit

serialVersionUID declarations use the <code>private</code> modifier where

possible, since such declarations apply only to the immediately declaring

class--serialVersionUID fields are not useful as inherited members. Array

classes cannot declare an explicit serialVersionUID, so they always have

the default computed value, but the requirement for matching

serialVersionUID values is waived for array classes.

2.6 实践

2.6.1 只增加serialVersionUID属性

如果我们只在1.1中指定serialVersionUID,再试一次,结果会怎么样?(没有增加sex哟)

操作步骤:我们在1.1中的类: Dog 增加serialVersionUID属性。

private static final long serialVersionUID = 1L;

再次运行结果:如1.2所示。

2.6.2 重复第2.1步骤哟,其它不变哟。

2.6.3 重复第2.2步骤,运行结果:正确 !

Dong{name='杨过', age=19, sex=0}

到此,关于“Java的Serializable接口怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI