Java对象序列化详细解析

合集下载

关于序列化和反序列化案例看这一篇就够用了,简直讲的清新脱俗!

关于序列化和反序列化案例看这一篇就够用了,简直讲的清新脱俗!

关于序列化和反序列化案例看这⼀篇就够⽤了,简直讲的清新脱俗!前⾔序列化:将java对象转化为可传输的字节数组反序列化:将字节数组还原为java对象为啥⼦要序列化?序列化最终的⽬的是为了对象可以跨平台存储,和进⾏⽹络传输。

⽽我们进⾏跨平台存储和⽹络传输的⽅式就是IO,⽽我们的IO⽀持的数据格式就是字节数组什么情况下需要序列化?凡是需要进⾏跨平台存储和⽹络传输的数据,都需要进⾏序列化本质上存储和⽹络传输都需要经过把⼀个对象状态保存成⼀种跨平台识别的字节格式,然后其他的平台才可以通过字节信息解析还原对象信息序列化的⽅式序列化只是⼀种拆装组装对象的规则,这种规则多种多样,常见的序列化⽅式有:JDK(不⽀持跨语⾔)、JSON、XML、Hessian、Kryo(不⽀持跨语⾔)、Thrift、Protostuff、FST(不⽀持跨语⾔)举个栗⼦⾃定义协议中,需要序列化和反序列化,案例中枚举类Algorithm的内部类重写了⾃定义接⼝Serializer中的序列化和反序列化⽅法,本案例中枚举类Algorithm采⽤了jdk和json两种序列化⽅式,通过配置类Config类,可以灵活在application.properties中选择序列化的⽅式导⼊依赖<!-- https:///artifact/com.google.code.gson/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version></dependency>⾃定义Message类package com.lian.chatroom.message;import lombok.Data;import java.io.Serializable;import java.util.HashMap;import java.util.Map;@Datapublic abstract class Message implements Serializable {private int sequenceId;private int messageType;/*** 根据消息类型的数字编号,获得对应的消息 class* @param messageType 消息类型字节* @return 消息 class*/public static Class<? extends Message> getMessageClass(int messageType) {return messageClasses.get(messageType);//定义抽象⽅法,获取返回消息类型public abstract int getMessageType();//⾃定义静态常量,每种数据类型以数字代表public static final int LoginRequestMessage = 0;public static final int LoginResponseMessage = 1;public static final int ChatRequestMessage = 2;public static final int ChatResponseMessage = 3;public static final int GroupCreateRequestMessage = 4;public static final int GroupCreateResponseMessage = 5;public static final int GroupJoinRequestMessage = 6;public static final int GroupJoinResponseMessage = 7;public static final int GroupQuitRequestMessage = 8;public static final int GroupQuitResponseMessage = 9;public static final int GroupChatRequestMessage = 10;public static final int GroupChatResponseMessage = 11;public static final int GroupMembersRequestMessage = 12;public static final int GroupMembersResponseMessage = 13;public static final int PingMessage = 14;public static final int PongMessage = 15;/*** 请求类型 byte 值*/public static final int RPC_MESSAGE_TYPE_REQUEST = 101;/*** 响应类型 byte 值*/public static final int RPC_MESSAGE_TYPE_RESPONSE = 102;//map存储(消息类型数字编号,消息类型)private static final Map<Integer, Class<? extends Message>> messageClasses = new HashMap<>();//static代码块随着类的加载⽽执⾏,⽽且只执⾏⼀次static {messageClasses.put(LoginRequestMessage, LoginRequestMessage.class);messageClasses.put(LoginResponseMessage, LoginResponseMessage.class);messageClasses.put(ChatRequestMessage, ChatRequestMessage.class);messageClasses.put(ChatResponseMessage, ChatResponseMessage.class);messageClasses.put(GroupCreateRequestMessage, GroupCreateRequestMessage.class);messageClasses.put(GroupCreateResponseMessage, GroupCreateResponseMessage.class);messageClasses.put(GroupJoinRequestMessage, GroupJoinRequestMessage.class);messageClasses.put(GroupJoinResponseMessage, GroupJoinResponseMessage.class);messageClasses.put(GroupQuitRequestMessage, GroupQuitRequestMessage.class);messageClasses.put(GroupQuitResponseMessage, GroupQuitResponseMessage.class);messageClasses.put(GroupChatRequestMessage, GroupChatRequestMessage.class);messageClasses.put(GroupChatResponseMessage, GroupChatResponseMessage.class);messageClasses.put(GroupMembersRequestMessage, GroupMembersRequestMessage.class);messageClasses.put(GroupMembersResponseMessage, GroupMembersResponseMessage.class);messageClasses.put(RPC_MESSAGE_TYPE_REQUEST, RpcRequestMessage.class);messageClasses.put(RPC_MESSAGE_TYPE_RESPONSE, RpcResponseMessage.class);}}⾃定义序列化接⼝⾃定义枚举类Algorithm,⽽枚举类Algorithm也有两个内部类对象 java和json,分别重写了接⼝的序列化和反序列化⽅法package com.lian.chatroom.protocol;import com.google.gson.Gson;import java.io.*;import java.nio.charset.StandardCharsets;/*** 为了⽀持更多的序列化⽅法*/public interface Serializer {/*** 反序列化* 将byte[]或json 转换为 java对象* @param bytes 字节数组* @param clazz 要转换成的java对象类型* @param <T> 泛型* @return*/<T> T deSerializer(byte[] bytes, Class<T> clazz);* 序列化* 将java对象转换为 byte[]或json类型*/<T> byte[] serializer(T object);/*** 创建内部枚举类 Algorithm,实现序列化*/enum Algorithm implements Serializer{//java代表是⾃带jdk的序列化与反序列化java{@Overridepublic <T> T deSerializer(byte[] bytes, Class<T> clazz) {try {ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); //对象输出流读取java对象return (T) ois.readObject();} catch (IOException | ClassNotFoundException e) {e.printStackTrace();throw new RuntimeException("反序列化失败", e);}}@Overridepublic <T> byte[] serializer(T object) {try {ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos);//将java对象写⼊到对象输出流中oos.writeObject(object);byte[] bytes = bos.toByteArray(); //返回字节数组return bytes;} catch (IOException e) {throw new RuntimeException("序列化失败", e);}}},json{@Overridepublic <T> T deSerializer(byte[] bytes, Class<T> clazz) {//将字节数组转换为字符串String json = new String(bytes, StandardCharsets.UTF_8);return new Gson().fromJson(json,clazz);}@Overridepublic <T> byte[] serializer(T object) {Gson gson = new Gson();//将java对象转化为json字符串String json = gson.toJson(object);//将json字符串转换为字节数组return json.getBytes(StandardCharsets.UTF_8);}}}}⾃定义协议类⾃定义的协议⾥需要编解码,序列化的⽅式,此处选择了jdk和jsonpackage com.lian.chatroom.protocol;import com.lian.chatroom.config.Config;import com.lian.chatroom.message.Message;import ty.buffer.ByteBuf;import ty.channel.ChannelHandler;import ty.channel.ChannelHandlerContext;import ty.handler.codec.MessageToMessageCodec;import lombok.extern.slf4j.Slf4j;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.util.List;/*** 必须和 LengthFieldBasedFrameDecoder ⼀起使⽤,确保接到的 ByteBuf 消息是完整的* 消息编解码* 出栈:ByteBuf格式数据转换为字符串等其他格式解码* ⼊栈:字符串等其他格式转换为 ByteBuf格式数据编码*/@Slf4j@ChannelHandler.Sharablepublic class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {@Overrideprotected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {//⽤通道分配⼀个缓存区ByteBuf out = ctx.alloc().buffer();//1. 4 字节的魔数,就是服务端和客户端约定好的暗号,例如:天王盖地虎宝塔镇魔妖out.writeBytes(new byte[]{1, 2, 3, 4});// 2. 1 字节的版本,out.writeByte(1);// 3. 1 字节的序列化⽅式 jdk 0 , json 1//out.writeByte(0); //写死的⽅式//3.1 采⽤配置类灵活选择序列化⽅式,返回此枚举常量的序号,如果序列化⽅式是jdk就会填写0,如果是json就会填写1 out.writeByte(Config.getSerializerAlgorithm().ordinal());// 4. 1 字节的指令类型out.writeByte(msg.getMessageType());// 5. 4 个字节out.writeInt(msg.getSequenceId());// ⽆意义,对齐填充out.writeByte(0xff);// 6. 获取内容的字节数组// ByteArrayOutputStream bos = new ByteArrayOutputStream();// ObjectOutputStream oos = new ObjectOutputStream(bos);// oos.writeObject(msg);// byte[] bytes = bos.toByteArray();//6.1、采⽤jdk⽅式序列化,将java对象转为字节数组//byte[] bytes = Serializer.Algorithm.java.serializer(msg);//6.2、采⽤json⽅式序列化//byte[] bytes = Serializer.Algorithm.json.serializer(msg);//6.3、采⽤配置类形式,来灵活选择使⽤哪种序列化⽅式byte[] bytes = Config.getSerializerAlgorithm().serializer(msg);// 7. 长度out.writeInt(bytes.length);// 8. 将字节数组写⼊到缓存区out.writeBytes(bytes);outList.add(out);}@Overrideprotected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {int magicNum = in.readInt();byte version = in.readByte();//从缓存区中读取到编码时⽤的哪种序列化算法类型,是jdk or json//返回 0 or 1, 0代表jdk序列化⽅式,1代表json序列化⽅式byte serializerAlgorithm = in.readByte();//消息类型,0,1,2,。

Java对象的序列化与反序列化-Json篇

Java对象的序列化与反序列化-Json篇

Java对象的序列化与反序列化-Json篇说到Java对象的序列化与反序列化,我们⾸先想到的应该是Java的Serializable接⼝,这玩意在两个系统之间的DTO对象⾥⾯可能会⽤到,⽤于系统之间的数据传输。

或者在RPC(远程⽅法调⽤)时可能会⽤到。

但其实若是⽤于数据传输,xml和json两种数据格式⽤得更多⼀些。

但是为什么不⽤XStream呢,XStream确实好⽤,但是在Applet环境下可以使⽤的xml类库也就只有jdom了,连dom4j在Applet环境下都没有权限使⽤(Java反射的某些特性是需要权限的,Applet的安全机制不允许)。

扯远了,本⽂要说的是Java对象与Json的相互转换。

⽬前Java常⽤的Json类库有3种,即fastjson、jackson和gson,分别介绍如何将⼀个Java对象转换成Json和将⼀个Json字符串转换成Java对象,其实它们的⽤法⼤同⼩异。

⼀、⾸先看Maven依赖⼆、需要序列化的POJO和初始化代码三、fastjson的使⽤四、jackson的使⽤五、gson的使⽤⼀、⾸先看Maven依赖若不会maven,请参考Maven的基本⽤法:1 <!-- json -->2 <!-- 引⼊fastjson依赖 -->3 <dependency>4 <groupId>com.alibaba</groupId>5 <artifactId>fastjson</artifactId>6 <version>1.2.12</version>7 </dependency>8 <!-- 引jackson依赖 -->9 <!-- jackson核⼼包,必选,提供基于“流模式”解析的API -->10 <dependency>11 <groupId>com.fasterxml.jackson.core</groupId>12 <artifactId>jackson-core</artifactId>13 <version>2.7.4</version>14 </dependency>15 <!-- jackson注解包,可选,提供注解功能 -->16 <dependency>17 <groupId>com.fasterxml.jackson.core</groupId>18 <artifactId>jackson-annotations</artifactId>19 <version>2.7.4</version>20 </dependency>21 <!-- jackson数据绑定包,可选,提供基于“对象绑定”和“树模型”相关API -->22 <dependency>23 <groupId>com.fasterxml.jackson.core</groupId>24 <artifactId>jackson-databind</artifactId>25 <version>2.7.4</version>26 </dependency>27 <!-- 引⼊gson依赖 -->28 <dependency>29 <groupId>com.google.code.gson</groupId>30 <artifactId>gson</artifactId>31 <version>2.6.2</version>32 </dependency>⼆、需要序列化的POJO和初始化代码以下3种类库的使⽤均使⽤下⾯这个POJO1public class User {2public User(){}3private String id;4private String name;5private String password;6public String getId() {7return id;8 }9public void setId(String id) {10this.id = id;11 }12public String getName() {13return name;14 }15public void setName(String name) { = name;17 }18public String getPassword() {19return password;20 }21public void setPassword(String password) {22this.password = password;23 }24 @Override25public String toString() {26return"User [id=" + id + ", name=" + name + ", password=" + password27 + "]";28 }29 }1/**2 * 初始化User对象3 * @return user4*/5private static User initUser(){6 User user = new User();7 user.setId("1");8 user.setName("jison");9 user.setPassword("jison");10return user;11 }三、fastjson的使⽤fastjson的主要⼯具类是JSON,以下代码实现Java对象的序列化与反序列化1// 将Java对象序列化为Json字符串2 String objectToJson = JSON.toJSONString(initUser());3 System.out.println(objectToJson);4// 将Json字符串反序列化为Java对象5 User user = JSON.parseObject(objectToJson, User.class);6 System.out.println(user);四、jackson的使⽤jackson我们经常⽤到的是它的数据绑定包下的ObjectMapper类,以下代码实现Java对象的序列化与反序列化ObjectMapper objectMapper = new ObjectMapper();// 将Java对象序列化为Json字符串String objectToJson = objectMapper.writeValueAsString(initUser());System.out.println(objectToJson);// 将Json字符串反序列化为Java对象User user = objectMapper.readValue(objectToJson, User.class);System.out.println(user);五、gson的使⽤gson的主要⼯具类是Gson,使⽤GsonBuilder构造,以下代码实现Java对象的序列化与反序列化1 Gson gson = new GsonBuilder().create();2// 将Java对象序列化为Json字符串3 String objectToJson = gson.toJson(initUser());4 System.out.println(objectToJson);5// 将Json字符串反序列化为Java对象6 User user = gson.fromJson(objectToJson, User.class);7 System.out.println(user);以上3种json类库的完整代码如下:1public class JsonUtils {23/**4 * 初始化User对象5 * @return user6*/7private static User initUser(){8 User user = new User();9 user.setId("1");10 user.setName("jison");11 user.setPassword("jison");12return user;13 }1415public static void main(String[] args) throws Exception {16// fastjson⽤法17 fastjson();18// jackson⽤法19 jackson();20// gson⽤法21 gson();22 }2324private static void fastjson(){25// 将Java对象序列化为Json字符串26 String objectToJson = JSON.toJSONString(initUser());27 System.out.println(objectToJson);28// 将Json字符串反序列化为Java对象29 User user = JSON.parseObject(objectToJson, User.class);30 System.out.println(user);31 }3233private static void jackson() throws Exception{34 ObjectMapper objectMapper = new ObjectMapper();35// 将Java对象序列化为Json字符串36 String objectToJson = objectMapper.writeValueAsString(initUser());37 System.out.println(objectToJson);38// 将Json字符串反序列化为Java对象39 User user = objectMapper.readValue(objectToJson, User.class);40 System.out.println(user);41 }4243private static void gson(){44 Gson gson = new GsonBuilder().create();45// 将Java对象序列化为Json字符串46 String objectToJson = gson.toJson(initUser());47 System.out.println(objectToJson);48// 将Json字符串反序列化为Java对象49 User user = gson.fromJson(objectToJson, User.class);50 System.out.println(user);51 }52 }。

什么是Java序列化,如何实现java序列化

什么是Java序列化,如何实现java序列化

什么是Java序列化,如何实现java序列化简要解释: 序列化就是⼀种⽤来处理对象流的机制,所谓对象流也就是将对象的内容进⾏流化。

可以对流化后的对象进⾏读写操作,也可将流化后的对象传输于⽹络之间。

序列化是为了解决在对对象流进⾏读写操作时所引发的问题。

序列化的实现:将需要被序列化的类实现Serializable接⼝,该接⼝没有需要实现的⽅法,implements Serializable只是为了标注该对象是可被序列化的,然后使⽤⼀个输出流(如:FileOutputStream)来构造⼀个ObjectOutputStream(对象流)对象,接着,使⽤ObjectOutputStream对象的writeObject(Object obj)⽅法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则⽤输⼊流。

详细解释:当两个进程在进⾏远程通信时,彼此可以发送各种类型的数据。

⽆论是何种类型的数据,都会以⼆进制序列的形式在⽹络上传送。

发送⽅需要把这个Java对象转换为字节序列,才能在⽹络上传送;接收⽅则需要把字节序列再恢复为Java对象。

只能将⽀持 java.io.Serializable 接⼝的对象写⼊流中。

每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引⽤的其他所有对象的闭包。

1.概念 序列化:把Java对象转换为字节序列的过程。

反序列化:把字节序列恢复为Java对象的过程。

2.⽤途 对象的序列化主要有两种⽤途: 1)把对象的字节序列永久地保存到硬盘上,通常存放在⼀个⽂件中; 2)在⽹络上传送对象的字节序列。

3.对象序列化序列化API java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)⽅法可对参数指定的obj对象进⾏序列化,把得到的字节序列写到⼀个⽬标输出流中。

java把对象转成json原理

java把对象转成json原理

java把对象转成json原理在Java编程中,对象是以一种特定的格式进行存储和传输的。

然而,在某些情况下,我们需要将Java对象转换成JSON(JavaScript对象表示法)格式,以便能够与其他系统进行交互。

本文将介绍Java将对象转换成JSON的原理及相关工具。

1. JSON简介JSON是一种用于数据交换的轻量级数据格式。

它由键值对组成,并使用大括号进行包裹。

键值对中的键和值之间使用冒号分隔,各个键值对之间使用逗号分隔。

JSON的值可以是字符串、数字、布尔值、数组、对象或者null。

2. Java对象转换成JSON的原理Java对象转换成JSON的过程称为序列化,而JSON转换成Java对象的过程称为反序列化。

Java提供了一些库和工具,可以帮助我们实现对象和JSON格式之间的转换。

2.1 使用Jackson库Jackson是在Java中进行JSON数据处理的最流行和常用库之一。

它提供了一系列的API,可以在Java对象和JSON格式之间进行转换。

Jackson的核心模块包括三大部分:Jackson Databind、Jackson Core和Jackson Annotations。

下面是一个使用Jackson库将Java对象转换成JSON格式的示例代码:```ObjectMapper objectMapper = new ObjectMapper();String json = objectMapper.writeValueAsString(object);```在这个示例中,我们首先创建了一个ObjectMapper对象,它是Jackson库中最重要的类之一。

然后,我们使用`writeValueAsString()`方法将Java对象转换成JSON字符串。

2.2 使用Gson库Gson是另一个常用的Java库,用于将Java对象转换成JSON格式和将JSON格式转换成Java对象。

它是由Google开发并维护的,具有良好的性能和易用性。

java map 反序列化方法

java map 反序列化方法

一、介绍Java中的Map是一种用于存储键值对的数据结构,常用的实现类包括HashMap、TreeMap和LinkedHashMap等。

在Java中,Map 的反序列化是指将Map类型的对象从字节流或者其他形式的序列化数据中恢复成原来的Map对象。

本文将介绍Java中Map的反序列化方法及其相关知识。

二、Map的序列化和反序列化Map的序列化和反序列化是Java中常见的操作,通过序列化可以将Map对象转换为字节流或者其他形式的数据,以便于存储或传输。

而反序列化则是将序列化的数据还原成原来的Map对象。

在Java中,Map的序列化和反序列化通常使用ObjectInputStream 和ObjectOutputStream来实现。

通过ObjectOutputStream可以将Map对象序列化为字节流,而ObjectInputStream则可以将字节流反序列化为Map对象。

三、Map的序列化和反序列化示例下面通过一个示例来演示如何将Map对象序列化为字节流,并将字节流反序列化为Map对象。

```javaimport java.io.*;import java.util.HashMap;import java.util.Map;public class MapSerializationDemo {public static void m本人n(String[] args) {// 创建一个Map对象Map<String, String> map = new HashMap<>();map.put("key1", "value1");map.put("key2", "value2");// 将Map对象序列化为字节流try (ByteArrayOutputStream bos = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(bos)) {oos.writeObject(map);byte[] bytes = bos.toByteArray();// 将字节流反序列化为Map对象try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes);ObjectInputStream ois = new ObjectInputStream(bis)) {Map<String, String> newMap = (Map<String, String>) ois.readObject();System.out.println(newMap);} catch (ClassNotFoundException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}}```在上面的示例中,首先创建了一个Map对象,并向其中添加了几个键值对。

serialize()序列化方法

serialize()序列化方法

serialize()序列化方法serialize()是一种常用的序列化方法,它能够将对象转化为可以存储或传输的格式,从而实现对象的持久化或跨网络的传输。

在本文中,我们将深入探讨serialize()方法的原理、用法和一些注意事项。

一、序列化的概念和作用序列化是指将对象转化为字节流的过程,这样可以方便地进行存储、传输或通过网络进行远程调用。

序列化后的数据可以被存储到文件中,也可以通过网络传输给其他设备或系统。

反序列化则是将字节流转化为对象的过程,实现了对象的恢复。

序列化的作用主要有以下几个方面:1. 对象持久化:通过将对象序列化为字节流,可以将对象存储到硬盘上,以实现对象的持久化,即使在程序退出后也能够将对象恢复到内存中使用。

2. 网络传输:通过序列化对象,可以将对象转化为字节流,从而方便地在网络上进行传输,实现分布式系统之间的通信。

3. 跨平台通信:不同编程语言之间可以通过序列化和反序列化来进行通信,实现跨平台的数据交换。

二、serialize()方法的使用在Java语言中,使用serialize()方法可以将一个对象序列化为字节流。

该方法存在于Serializable接口中,因此需要对要序列化的类进行实现Serializable接口。

下面是一个示例代码:import java.io.*;public class SerializationDemo implements Serializable {public static void main(String[] args) {// 创建一个对象Student student = new Student("Tom", 20, "Male");try {// 创建一个输出流FileOutputStream fileOut = new FileOutputStream("student.ser");// 创建一个对象输出流ObjectOutputStream out = new ObjectOutputStream(fileOut);// 序列化对象out.writeObject(student);// 关闭输出流out.close();fileOut.close();System.out.println("对象已序列化并存储在student.ser 文件中");} catch (IOException e) {e.printStackTrace();}}}在上述代码中,我们创建了一个Student类,并实现了Serializable接口。

java嵌套对象序列化_java–使用RestTemplate反序列化嵌套对象

java嵌套对象序列化_java–使用RestTemplate反序列化嵌套对象

java嵌套对象序列化_java–使用RestTemplate反序列化嵌套对象使用RestTemplate反序列化嵌套对象是在Java中进行网络请求和处理返回数据的一种常见方式。

在这个过程中,我们通常会遇到需要将返回的数据序列化成嵌套对象的情况。

嵌套对象是指一个对象中包含了其他对象作为其属性或字段的情况。

例如,假设我们有一个User对象,其中包含一个Address对象作为其属性。

在进行网络请求时,我们可能会得到一个包含User对象的JSON字符串,其中包含了Address对象的信息。

首先,我们需要定义一个User类和一个Address类来表示嵌套对象的结构。

```javapublic class Userprivate String name;private int age;private Address address;// 省略构造函数、getter和setter方法public class Addressprivate String city;private String street;private int zipCode;// 省略构造函数、getter和setter方法```接下来,我们可以使用RestTemplate来发送网络请求,并将返回的数据反序列化成嵌套对象。

```javaRestTemplate restTemplate = new RestTemplate(;User user = restTemplate.getForObject(url, User.class);```在这里,我们使用RestTemplate的`getForObject`方法发送GET请求,并将返回的JSON字符串反序列化成User对象。

但是,这样的方式只能将最外层的User对象正确反序列化,而不能正确反序列化嵌套的Address对象。

为了解决这个问题,我们需要使用Jackson库提供的`TypeReference`类。

serializable的注解

serializable的注解

serializable的注解
Serializable是Java中的一个接口,用于标识一个类的实例
可以被序列化。

在Java中,序列化是指将对象转换为字节流的过程,以便可以将其保存到文件、数据库或者通过网络传输。

Serializable接口没有任何方法或字段,它只是一个标记接口,用
于指示实现了该接口的类的对象可以被序列化。

在实际应用中,我
们可以通过在类的定义中添加`implements Serializable`来实现该
接口。

在Java中,如果一个类的实例需要被序列化,那么该类必须实
现Serializable接口。

否则,在序列化的过程中会抛出NotSerializableException异常。

通过实现Serializable接口,
我们可以确保对象的所有状态可以被保存和恢复,包括对象的属性
和引用。

在使用Serializable接口时,需要注意以下几点:
1. 序列化的类的所有属性都应该是可序列化的,或者标记为transient,表示这些属性不参与序列化过程。

2. 序列化和反序列化的类的版本号应该保持一致,可以通过添加serialVersionUID字段来手动指定版本号,以避免在类结构发生变化时导致序列化失败。

3. 序列化的类的父类如果不是可序列化的,需要确保父类的构造函数可以被子类调用,否则会导致序列化失败。

总之,Serializable接口是Java中用于标识类的实例可以被序列化的接口,通过实现该接口,我们可以在Java中轻松实现对象的序列化和反序列化操作。

transient在java中的用法

transient在java中的用法

transient在java中的用法在Java编程语言中,transient关键字用于控制对象序列化的过程。

在本文中,我将为您详细介绍transient的用法,并逐步解释其在序列化中的作用。

1. 什么是序列化?在Java中,序列化是将对象的状态转换为字节流的过程,以便将其存储在磁盘上或通过网络传输。

反序列化则是将字节流转换回对象的过程。

通过序列化,我们可以方便地传输和存储对象。

2. 为什么需要transient?在某些情况下,我们可能不希望将对象的某些属性进行序列化。

一些属性,例如敏感数据或计算得出的临时结果,可能不适合被持久化。

此时,我们可以使用transient关键字来标记这些属性,告诉Java虚拟机不要将其序列化。

3. 如何使用transient?在Java中,我们只需在不希望被序列化的属性前添加transient关键字。

例如,假设我们有一个Person类,其中包含姓名和密码两个属性,我们不希望将密码属性序列化,可以将其声明为transient:public class Person implements Serializable {private String name;private transient String password;省略构造函数和其他方法}在上述示例中,name属性将被正常序列化,而password属性将被忽略。

4. transient的序列化过程当对象被序列化时,Java虚拟机会自动忽略transient修饰的属性。

在序列化过程中,Java会将对象转换为字节流,但不包括transient属性。

因此,序列化后字节流中不包含transient属性的值。

5. transient的反序列化过程当对象从字节流中反序列化回来时,transient属性将被初始化为默认值,而不是之前的值。

对于基本数据类型,transient属性将被初始化为对应类型的默认值(如0,false等)。

java序列化方式性能比较

java序列化方式性能比较

java序列化⽅式性能⽐较1、Total Time (“total”)创建⼀个对象,将其序列化成⼀个字节数组,然后再反序列化成⼀个对象。

2、Serialization Time (“ser”)创建⼀个对象,将其序列化成⼀个字节数组。

3、Deserialization Time (“deser+deep”)相⽐于序列化,反序列化更耗时。

为了更公平的⽐较,jvm-serializers在反序列化测试时访问了反序列化得到的对象的所有字段(也就是deep的含义),因为部分⼯具反序列化时“偷懒”⽽没有做⾜⼯作。

4、Serialized Size (“size”)序列化数据的⼤⼩,这个⼤⼩会依赖于使⽤的数据。

5、Serialization Compressed Size (“size+dfl”)使⽤java内置的DEFLATE(zlib)压缩的序列化数据的⼤⼩。

6、Object Creation Time (“create”)对象创建耗时很短(平均100纳秒)所以通常的⽐较没什么意义。

不过,不同⼯具创建的对象在表现上会有不同。

有的⼯具只是创建普通的java类,你可以直接访问其字段,⽽有的使⽤get/set⽅法,有的使⽤builder模式。

分析这些对⽐,java内置的序列化⽅式性能很差(这才催⽣了各种序列化⼯具)。

在这些⼯具中,protostuff表现极为出⾊,盖过了名头响亮的protobuff和thrift。

通⽤格式中,json要⽐xml强不少,⽽不同⼯具对同样格式的性能表现也有差别,这也给了选择⼯具的⼀个指导。

另⼀个值得⼀提的是bson,尽管jvm-serializers没有包含它,相信性能上应该不错。

也可以参考jvm-serializers已有⼯具评测代码的实现,添加⽐如处理bson、php等格式的序列化⼯具的评测。

java序列化的原理

java序列化的原理

java序列化的原理Java序列化是指将一个对象的状态信息转换为可以存储或传输的形式的过程。

具体来说,序列化就是将一个对象转换为一个字节流,以便将其写入文件、发送到网络上或者进行其他形式的持久化存储。

一旦对象被序列化,就可以在需要的时候被反序列化回原来的状态。

Java序列化的主要原理如下:1. 标记对象:序列化机制通过在类中添加一个特殊的序列化注解(如Serializable)来标记可以被序列化的类。

如果一个类被标记为可序列化,那么它的所有非瞬态和非静态字段都将被序列化。

2. 跟踪依赖关系:如果一个对象的字段引用了一个可序列化的对象,那么这个引用字段将被序列化。

如果一个对象的字段引用了另一个对象,而这个被引用对象是不可序列化的,那么这个引用字段将被序列化为一个特殊的标记(如null或者一个字符串)。

3. 生成序列化ID:每个可序列化的类都有一个唯一的序列化ID。

这个ID 用于在反序列化时验证类的版本。

如果类的结构发生变化,序列化ID也需要改变。

4. 转换数据:在序列化过程中,对象的字段值将被转换为字节流。

这个转换过程包括类型检查、数据转换和编码等步骤。

5. 写入数据流:将转换后的字节流写入到输出流中。

这个输出流可能是文件输出流、网络输出流或者其他类型的输出流。

6. 反序列化:在反序列化过程中,字节流被读取并转换回原来的对象。

这个过程与序列化过程相反,包括解码、数据转换和验证等步骤。

Java序列化的实现方式是通过实现接口。

当一个类实现了Serializable接口后,它的对象就可以被序列化和反序列化。

在实际应用中,我们通常不需要手动实现Serializable接口,只需要在类上添加Serializable注解即可。

序列化的概念

序列化的概念

序列化的概念
序列化是指将一个对象的状态转换为可以存储或传输的形式,方便将对象的状态保存和恢复,在特定的语言和操作系统之间传输等等,用于提高传输效率和改善性能。

序列化可以将对象的信息保存到文件中,以便将来可以恢复。

也可以将对象的信息进行网络传输,用于客户端和服务器之间的通信。

序列化可以实现对象的持久化。

序列化过程主要包括:将一个对象状态转换为一种可存储的形式:将一个对象状态转移在不同进程空间中保持一致性:在序列化过程中实现对象的深复制等功能。

序列化一般可以分为三大类:文本序列化、二进制序列化、对象序列化。

文本序列化使用文本格式,它将数据格式简单地存放在一个文本文件中,便于阅读和编辑,但不易于传输。

二进制序列化使用二进制格式,它将数据格式以二进制格式存放在文件中,便于传输,但不易于阅读和编辑。

对象序列化是Java语言提供的一种特殊的序列化方式,它将对
象的结构和属性封装在一个数据结构中,能够把Java对象转换为字
节序列,可以将Java对象以字节流的形式保存在磁盘上,也可以将Java对象以字节流的形式通过网络传输。

- 1 -。

java创建对象的三种方法

java创建对象的三种方法

java创建对象的三种方法在Java中,创建对象有三种常用的方法,分别是使用new关键字、使用反射和使用序列化。

以下将详细介绍这三种方法的使用。

1. 使用new关键字创建对象:使用new关键字是创建Java对象最常用和简单的方法之一。

通过该关键字,我们可以调用指定类的构造方法来创建一个新的对象。

具体步骤如下:```ClassName objectName = new ClassName();```其中,`ClassName`是要创建对象的类名,`objectName`是创建的对象的引用。

使用该方法创建对象时,JVM会执行以下操作:1) 在堆内存中为对象分配一块内存空间。

2) 调用对象的构造方法,对对象进行初始化。

3) 返回对象的引用,可以通过该引用来访问、修改对象的属性和方法。

2. 使用反射创建对象:Java的反射机制允许在运行时动态地创建类的对象,无需提前知道类的详细信息。

使用反射创建对象需要使用到`ng.reflect`包。

以下是使用反射创建对象的步骤:1) 获取要创建对象的类的`Class`对象。

2) 使用`newInstance()`方法创建对象的实例。

下面是一个示例代码:```Class<?> cls = Class.forName("ClassName");Object object = cls.newInstance();```其中,`ClassName`是要创建对象的类名,`object`是创建的对象的引用。

使用反射创建对象时,JVM会执行以下操作:1) 加载类和其父类。

2) 分配对象的内存空间。

3) 设置对象的初始值。

4) 执行构造函数。

3. 使用序列化创建对象:序列化是将Java对象转换为字节流,以便可将其保存到文件、数据库中或进行网络传输。

通过序列化和反序列化可以创建和恢复一个对象的副本。

要使用序列化创建对象,需要实现`java.io.Serializable`接口。

serializable原理

serializable原理

serializable原理
Serializable是一种Java语言提供的序列化接口,它的作用是将Java对象转换为可存储或传输的格式,例如将对象写入文件或通过网络传输。

在Serializable接口的帮助下,Java对象被转换为字节数组,从而可以被存储、传输和恢复。

具体原理如下:
1. Java对象被转换为字节数组:当一个Java对象被标记为Serializable时,Java会将其转换为字节数组。

这个过程是自动的,并且可以通过Java IO存储和传输。

2. 序列化数据的存储和传输:Java序列化工具可以将Java对象序列化存储在磁盘上,也可以将其通过网络传输给其他计算机或Java虚拟机。

这个过程也是自动的,只需要将对象传给序列化方法即可。

3. 字节数组恢复为Java对象:当字节数组被传回程序时,这些数据可以被反序列化,转换为原来的Java对象。

这个过程也是自动的,只需要使用Java反序列化方法将字节数组反序列化即可。

总之,Serializable是Java提供的一种便捷的序列化机制,使得Java对象的存储和传输变得更加方便。

它的原理就是将对象转换为字节数组,存储或传输给其他地方,然后再将字节数组还原为原来的Java对象。

JAVA使用SnakeYAML解析与序列化YAML

JAVA使用SnakeYAML解析与序列化YAML

JAVA使⽤SnakeYAML解析与序列化YAML1.概述本⽂,我们将学习如何使⽤库将YAML⽂档转换为Java对象,以及JAVA对象如何序列化为YAML⽂档。

2.项⽬设置要在项⽬中使⽤SnakeYAML,需要添加Maven依赖项(可在找到最新版本):<dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.25</version></dependency>3.⼊⼝点该YAML类是API的⼊⼝点:Yaml yaml = new Yaml()由于实现不是线程安全的,因此不同的线程必须具有⾃⼰的Yaml实例。

4.加载YAML⽂档SnakeYAML⽀持从String或InputStream加载⽂档,我们从定义⼀个简单的YAML⽂档开始,然后将⽂件命名为customer.yaml:firstName: "John"lastName: "Doe"age: 204.1。

基本⽤法现在,我们将使⽤Yaml类来解析上述YAML⽂档:Yaml yaml = new Yaml();InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("customer.yaml");Map<String, Object> obj = yaml.load(inputStream);System.out.println(obj);上⾯的代码⽣成以下输出:{firstName=John, lastName=Doe, age=20}默认情况下,load()⽅法返回⼀个Map对象。

serializable类型字段转对象-概述说明以及解释

serializable类型字段转对象-概述说明以及解释

serializable类型字段转对象-概述说明以及解释1.引言概述部分的内容可以描述一下serializable类型字段的基本概念和作用,以及为什么将其转为对象是一个重要的需求。

下面是一个可能的概述部分的例子:引言1.1 概述在软件开发过程中,我们经常会遇到需要在不同的应用程序或不同的系统之间传输数据的情况。

其中,使用serializable类型字段来存储和传输数据是一种常见的方式。

Serializable是Java中的一个接口,它的作用是标识一个类的实例可以被序列化,即可以将对象转化为字节序列以便在网络上传输或者保存到文件中。

通过将对象序列化为字节流,我们可以实现跨平台、跨语言的数据传输和存储。

然而,将数据以serializable类型字段的形式进行传输或存储并不方便,因为它们往往是以二进制的形式存在,不易读取和理解。

因此,将serializable类型字段转为对象是一个非常重要的需求。

通过将其转为对象,我们可以更方便地对数据进行操作、分析和理解。

另外,将serializable 类型字段转为对象也可以帮助我们更好地利用对象的属性和方法,从而实现更复杂的功能。

本文将介绍如何将serializable类型字段转为对象,并探讨转换它们的重要性和未来可能的发展方向。

深入了解和应用这些技术,将会大大提高我们在数据处理和系统集成中的效率和灵活性。

接下来,让我们一起来探索吧。

文章结构的目的是为了帮助读者更好地理解文章的组织和内容安排。

本文的文章结构如下:1. 引言1.1 概述1.2 文章结构1.3 目的2. 正文2.1 什么是serializable类型字段2.2 为什么需要将serializable类型字段转为对象2.3 如何将serializable类型字段转为对象3. 结论3.1 总结3.2 对转换serializable类型字段的重要性进行强调3.3 展望未来可能的发展方向在本文的文章结构中,引言部分介绍了文章的背景和目的。

protostuff原理(一)

protostuff原理(一)

protostuff原理(一)Protostuff简介什么是Protostuff?Protostuff是一个Java序列化框架,它提供了一种快速、高效的方式来将对象序列化为字节流,以便在网络上进行传输或持久化存储。

Protostuff的主要特点•快速:Protostuff提供了一种基于字节码生成器的序列化方式,因此在序列化和反序列化过程中非常高效。

•轻量级:Protostuff本身不依赖于其他第三方库,只需引入Protostuff的核心库即可。

•易于使用:Protostuff的API设计简洁明了,使用起来非常方便。

•兼容性强:Protostuff支持兼容性非常好,即使在对象模式发生变化时,也能够正确处理。

Protostuff的原理解析Protostuff的序列化过程1.根据Java对象的定义,Protostuff使用字节码生成器动态生成序列化代码。

2.在对象序列化时,代码生成器会根据对象的结构和类型信息将对象转换为字节流。

3.将生成的字节流传输或存储。

4.在对象反序列化时,使用相同的字节码生成器将字节流转换为Java对象。

Protostuff的核心概念•Schema(模式):在Protostuff中,Schema是描述对象结构和类型的关键概念。

每个Java对象都对应一个Schema,它定义了对象的字段和类型信息。

•RuntimeSchema(运行时模式):RuntimeSchema是Schema的一个实现,它通过反射来生成模式,避免了在编译期生成Schema的麻烦。

•LinkedBuffer(链式缓冲区):LinkedBuffer是Protostuff中用于缓存序列化过程中一系列的字节数组的缓冲区。

它能够提高序列化的效率。

Protostuff的使用示例public class User {private int id;private String name;// Getter and Setter methods}public class ProtostuffSerializer {public static byte[] serialize(User user) { Schema<User> schema = ();LinkedBuffer buffer = (_BUFFER_SIZE);return (user, schema, buffer);}public static User deserialize(byte[] data) { Schema<User> schema = ();User user = ();(data, user, schema);return user;}}public class Main {public static void main(String[] args) {User user = new User();(1);("John");byte[] serializedData = (user);User deserializedUser = (serializedData); (()); // Output: John}}以上是一个简单的使用Protostuff进行对象序列化的示例。

bytearrayseserializer 中文

bytearrayseserializer 中文

标题:深度解析 bytearrayseserializer在现代编程中,序列化是一项十分重要且常见的操作。

而在 Java 中,有很多种不同的方式来进行序列化,其中之一就是使用BytearraySerializer。

本文将深入探讨 bytearrayserializer,帮助读者全面理解这一概念。

1. 什么是 bytearrayserializer?bytearrayserializer 是 Java 中的一种序列化方式,它可以将对象转换成 byte 数组,以便于网络传输或者存储到文件中。

在序列化和反序列化过程中,bytearrayserializer 将对象转换成字节数组,并在需要时将其还原成原始对象。

2. bytearrayserializer 的使用场景bytearrayserializer 在实际开发中有着广泛的应用场景。

比如在分布式系统中,需要将对象进行序列化后进行网络传输;在缓存存储中,也可以将对象序列化为字节数组后存储到内存或者文件中;另外,在一些需要持久化存储的场景中,也可以使用 bytearrayserializer 来将对象转换成字节数组后进行存储。

3. bytearrayserializer 的优缺点优点:bytearrayserializer 使用简单、高效,并且能够把对象序列化成字节数组,并且是无损的。

缺点:当对象的结构比较复杂时,可能会导致序列化的字节数组过大,从而影响网络传输和存储的效率;另外,bytearrayserializer 对象序列化之后的字节数组不易阅读,不方便调试。

4. bytearrayserializer 的实现原理在 Java 中,bytearrayserializer 的实现原理是通过将对象转换为字节数组,并在需要时将字节数组还原为原始对象。

这一过程中,会涉及到对象的各种属性和字段的读取和写入,以及对象的生命周期管理等方面。

5. 个人观点和理解在我看来,bytearrayserializer 虽然简单高效,但在实际应用中也需要注意一些问题。

java json序列化原理

java json序列化原理

java json序列化原理Java中的JSON序列化是指将Java对象转换为JSON格式的字符串的过程。

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于前后端数据传输和存储。

JSON格式的数据由键值对组成,并使用大括号{}包裹,键值对之间使用逗号分隔。

JSON序列化的过程是将Java对象的属性值映射到JSON格式的字符串中。

在Java中,可以使用多种方式实现JSON序列化,如手动拼接字符串、使用第三方库(如Jackson、Gson等)或使用Java内置的JSON库(如JSONObject、JSONArray等)。

我们来看看JSON序列化的基本原理。

在Java中,一个对象可以通过访问其属性来获取属性值。

JSON序列化就是通过访问对象的属性,将属性值转换为JSON格式的字符串。

具体步骤如下:1. 创建一个空的JSON对象或JSON数组,用于存储属性值。

2. 遍历对象的属性,获取属性名和属性值。

3. 根据属性值的类型,将属性名和属性值转换为JSON格式的字符串并添加到JSON对象或数组中。

4. 将JSON对象或数组转换为字符串表示。

在实际应用中,可以使用不同的方式实现JSON序列化。

下面以使用Jackson库为例,介绍其工作原理。

Jackson是一个流行的Java库,用于处理JSON数据。

它提供了一组API,用于将Java对象序列化为JSON格式的字符串,或将JSON 字符串反序列化为Java对象。

Jackson使用基于注解的方法来定义Java对象和JSON之间的映射关系。

在使用Jackson进行JSON序列化时,首先需要在Java对象的属性上添加相应的注解,以指定属性和JSON字段之间的映射关系。

常用的注解包括@JsonProperty、@JsonInclude、@JsonFormat等。

这些注解可以指定属性名、属性的序列化规则、属性的格式等。

接下来,通过创建ObjectMapper对象来实现JSON序列化。

tostringserializer 原理

tostringserializer 原理

tostringserializer 原理Tostringserializer 是一个序列化器,用于将对象序列化成字符串。

其原理是将对象转换成一定格式的字符串,以便于在不同的系统之间传输和存储。

在Java 中,ToStringSerializer 是Jackson 序列化库中的一部分,可以通过以下方式使用该序列化器:1. 创建ObjectMapper 对象,该对象是Jackson 序列化库中的核心2. 通过调用ObjectMapper 对象的setSerializer 方法来设置序列化器为ToStringSerializer3. 将需要序列化的对象传入ObjectMapper 对象的writeValueAsString 方法中,即可将对象序列化成字符串例如,以下代码展示了如何使用ToStringSerializer 将一个Person 对象序列化成JSON 字符串:```javaimport com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import java.io.IOException;public class JacksonToStringSerializerExample {public static void main(String[] args) throws IOException { Person person = new Person("Alice", 25);ObjectMapper mapper = new ObjectMapper();mapper.getSerializerProvider().setNullValueSerializer(new ToStringSerializer());String result = mapper.writeValueAsString(person);System.out.println(result);}}class Person {private String name;private int age;public Person(String name, int age) { = name;this.age = age;}// getters and setters}```输出结果为:```{"name":"Alice","age":25}```可以看到,Person 对象被序列化成了一个JSON 格式的字符串。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java对象序列化详细解析Bean Serializable Interface 的接口让BEAN可以串行化,将其变成一个可保存为以后使用的二进制流。

当一个BEAN被系列化到磁盘上或者其他任何地方,其状态被保存起来,其中的属性值也不会改变。

在BEAN的规范中,JSP并没有要求BEAN实现Serial izable接口。

但是,如果您希望自己控制您所创建的组件的serialization进程,或者您想serialize并不是标准组件扩展的组件,您必须了解serialization and deserialization的细节。

有几个原因你会把BEAN冷藏起来以备后用。

有些服务器通过将所有的SESSION 数据(包括BEAN)写入磁盘来支持任意长的SESSION生命期,即使服务器停机也不会丢失。

当服务器重新启动后,串行化的数据被恢复。

同样的理由,在重负载的站点上支持服务器分簇的环境中,许多服务器通过串行化来复制SESSION。

如果你的BEAN不支持串行化,服务器就不能正确地保存和传输类。

通过同样的策略,你可以选择将BEAN保存在磁盘上或者数据库中,以备后用。

例如,也许可以将客户的购物车实现为一个BEAN,在访问期间将其保存在数据库中。

如果BEAN需要特殊的复杂的初始设置,可以将BEAN设置好后串行化保存在磁盘上。

这个BEAN的“快照”可以用在任何需要的地方,包括在$#@60;jsp:useBean$#@62;中用beanName属性的调用。

$#@60;jsp:useBean$#@62;标签中的beanName属性,用来实例化一个串行化的BEAN,而不是用来从一个类创建一个全新的实例。

如果BEAN还没有创建,beanNa me属性传给java.beans.Bean.instantiate()方法,由类装载器对类进行实例化。

它首先假定存在一个串行化的BEAN(带有扩展名.ser),然后会将其激活。

如果这个操作失败,它就会实例化一个新的实例。

下面简单介绍一下这个接口:对象能包含其它的对象,而这其它的对象又可以包含另外的对象。

JAVA serializatio n能够自动的处理嵌套的对象。

对于一个对象的简单的域,writeObject()直接将值写入流。

而,当遇到一个对象域时,writeObject()被再次调用,如果这个对象内嵌另一个对象,那么,writeObject() 又被调用,直到对象能被直接写入流为止。

程序员所需要做的是将对象传入ObjectOutputStream 的writeObject() 方法,剩下的将又系统自动完成。

下面的例子创建了一个调用mine对象的PersonalData对象。

代码实现的是将一个串和mine 对象输出到一个流,并存入一个文件:public class PersonalData implements Serializable {public int idpublic int yearOfBirth;public float yearlySalary;}PersonalData mine = new PersonalData(101, 1956, 46500.00); FileOutputStream outstream = new FileOutputStream("PersonalData.ser"); ObjectOutputStream out = new ObjectOutputStream(outstream);out.writeObject("My personal data"); //将一个串写入流out.writeObject(mine); //将这个对象写入流out.close(); // 清空并关闭流...一个FileOutputStream对象被创建且传到一个ObjectOutputStream。

当out.wr iteObject() 被调用,这个串和mine 对象被objects are serializ顺序加入一个存入文件PersonalData.ser的字节对列。

您应该注意上述类是实现的java.io.Serializable接口。

因为它并未指定要实现的方法,所以Serializable被称为"tagging interface" ,但是它仅仅"tags"它自己的对象是一个特殊的类型。

任一个您希望serialize的对象都应该实现这个接口。

这是必须的。

否则,用到流技术时将根本不工作。

例如,如果您试着去serialize 一个没有实现这个接口的对象,一个NotSerializableException将产生。

类通过实现java.io.Serializable 接口以启用其序列化功能。

未实现此接口的类将无法使其任何状态序列化或反序列化。

可序列化类的所有子类型本身都是可序列化的。

序列化接口没有方法或字段,仅用于标识可序列化的语义。

Java的"对象序列化"能让你将一个实现了Serializable接口的对象转换成一组byte,这样日后要用这个对象时候,你就能把这些byte数据恢复出来,并据此重新构建那个对象了。

要想序列化对象,你必须先创建一个OutputStream,然后把它嵌进ObjectOutput Stream。

这时,你就能用writeObject( )方法把对象写入OutputStream了。

writeObject 方法负责写入特定类的对象的状态,以便相应的readObject 方法可以还原它。

通过调用out.defaultWriteObject 可以调用保存Object 的字段的默认机制。

该方法本身不需要涉及属于其超类或子类的状态。

状态是通过使用writeObject 方法或使用DataOutput 支持的用于基本数据类型的方法将各个字段写入ObjectOutputStream 来保存的。

读的时候,你得把InputStream嵌到ObjectInputStream里面,然后再调用readObject( )方法。

不过这样读出来的,只是一个Object的reference,因此在用之前,还得先下传。

readObject 方法负责从流中读取并还原类字段。

它可以调用in.defaultRe adObject 来调用默认机制,以还原对象的非静态和非瞬态字段。

defaultReadObject 方法使用流中的信息来分配流中通过当前对象中相应命名字段保存的对象的字段。

这用于处理类发展后需要添加新字段的情形。

该方法本身不需要涉及属于其超类或子类的状态。

状态是通过使用writeObject 方法或使用DataOutput 支持的用于基本数据类型的方法将各个字段写入ObjectOutputStream 来保存的。

看一个列子:import java.io. * ;class tree implements java.io.Serializable {public tree left;public tree right;public int id;public int level;private static int count = 0 ;public tree( int depth) {id = count ++ ;level = depth;if (depth > 0 ) {left = new tree(depth - 1 );right = new tree(depth - 1 );}}public void print( int levels) {for ( int i = 0 ; i < level; i ++ )System.out.print( " " );System.out.println( " node " + id);if (level <= levels && left != null)left.print(levels);if (level <= levels && right != null)right.print(levels);}public static void main (String argv[]) {try{/*创建一个文件写入序列化树。

*/FileOutputStream ostream = new FileOutputStream( " tree.tmp " );/*创建输出流*/ObjectOutputStream p = new ObjectOutputStream(ostream);/*创建一个二层的树。

*/tree base = new tree( 2 );p.writeObject(base); //将树写入流中。

p.writeObject( " LiLy is 惠止南国" );p.flush();ostream.close(); //关闭文件。

/*打开文件并设置成从中读取对象。

*/FileInputStream istream = new FileInputStream( " tree.tmp " );ObjectInputStream q = new ObjectInputStream(istream);/*读取树对象,以及所有子树*/tree new_tree = (tree)q.readObject();new_tree.print( 2 ); //打印出树形结构的最上面2级String name = (String)q.readObject();System.out.println( " \n " + name);} catch (Exception ex) {ex.printStackTrace();}}}最后结果如下:node 0node 1node 2node 3node 4node 5node 6LiLy is 惠止南国可以看到,在序列化的时候,writeObject与readObject之间的先后顺序。

readOb ject将最先write的object read出来。

用数据结构的术语来讲就姑且称之为先进先出吧!在序列化时,有几点要注意的:1:当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。

2:如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。

3:如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。

相关文档
最新文档