这篇文章主要介绍“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
二、例子
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 strongly recommended 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 unexpectedInvalidClassException
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 theprivate
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接口怎么使用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!