- 浏览: 1505291 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (798)
- struts2 (42)
- servlet (20)
- quartz (4)
- jquery & ajax (24)
- tomcat (5)
- javascript (15)
- struts1 (8)
- 搜索关键字及链接 (3)
- fckeditor (3)
- Apache (5)
- spring (22)
- linux (3)
- 企业应用 (8)
- 综合应用 (13)
- 服务器 (2)
- 数据库 (85)
- 性能调优 (21)
- 网络应用 (15)
- 缓存技术 (8)
- 设计模式 (39)
- 面试题 (7)
- 程序人生&前辈程序员 (29)
- java基础 (59)
- hibernate (75)
- log4j (4)
- http (11)
- 架构设计 (28)
- 网页设计 (12)
- java邮件 (4)
- 相关工具 (11)
- ognl (7)
- 工作笔记 (18)
- 知识面扩展 (12)
- oracle异常 (1)
- 正则表达式 (2)
- java异常 (5)
- 项目实践&管理 (1)
- 专业术语 (11)
- 网站参考 (1)
- 论坛话题 (2)
- web应用 (11)
- cxf&webservice (22)
- freemarker (3)
- 开源项目 (9)
- eos (1)
- ibatis (6)
- 自定义标签 (3)
- jsp (3)
- 内部非公开文档(注意:保存为草稿) (0)
- 国内外知名企业 (2)
- 网店 (3)
- 分页 (1)
- 消费者习惯 (2)
- 每日关注 (1)
- 商业信息 (18)
- 关注商业网站 (1)
- 生活常识 (3)
- 新闻 (2)
- xml&JSON (5)
- solaris (1)
- apache.common (3)
- BLOB/CLOB (1)
- lucene (2)
- JMS (14)
- 社会进程 (8)
- SSH扩展 (2)
- 消费心理 (1)
- 珠三角 (1)
- 设计文档 (1)
- XWork&webwork (1)
- 软件工程 (3)
- 数据库及链接 (1)
- RMI (2)
- 国内外知名企业&人物 (1)
最新评论
-
司c马:
简介易懂、
OutputStream和InputStream的区别 -
在世界的中心呼喚愛:
解决我的问题
Java获取客户端的真实IP地址 -
bo_hai:
都是些基本的概念呀!
SSO -
tian_4238:
哥们,你也是搞水利这块的吧。
巧用SQLQuery中的addScalar -
loveEVERYday:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp小结
java 为什么序列化?为什么不是所有的类序列化? 收藏
为什么JAVA要实现对象序列化
简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!
如上所述,读写对象会有什么问题呢?比如:我要将对象写入一个磁盘文件而后再将其读出来会有什么问题吗?别急,其中一个最大的问题就是对象引用!举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
以下序列化机制的解决方案:
1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)
2.当要保存一个对象时,先检查该对象是否被保存了。
3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象
通过以上的步骤序列化机制解决了对象引用的问题!
序列化的实现
将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
修改默认的序列化机制
在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,这样的话我们也必须把他标注为transient,可是不能写入又怎么恢复呢?好在序列化机制为包含这种特殊问题的类提供了如下的方法定义:
private void readObject(ObjectInputStream in) throws
IOException, ClassNotFoundException;
private void writeObject(ObjectOutputStream out) throws
IOException;
(注:这些方法定义时必须是私有的,因为不需要你显示调用,序列化机制会自动调用的)
使用以上方法我们可以手动对那些你又想序列化又不可以被序列化的数据字段进行写出和读入操作。
下面是一个典型的例子,java.awt.geom包中的Point2D.Double类就是不可序列化的,因为该类没有实现Serializable接口,在我的例子中将把它当作LabeledPoint类中的一个数据字段,并演示如何将其序列化!
view plaincopy to clipboardprint?
import java.io.*;
import java.awt.geom.*;
public class TransientTest
{
public static void main(String[] args)
{
LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00);
try
{
System.out.println(label);//写入前
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("Label.txt"));
out.writeObject(label);
out.close();
System.out.println(label);//写入后
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("Label.txt"));
LabeledPoint label1 = (LabeledPoint)in.readObject();
in.close();
System.out.println(label1);//读出并加1.0后
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class LabeledPoint implements Serializable
{
public LabeledPoint(String str, double x, double y)
{
label = str;
point = new Point2D.Double(x, y);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
/**
*必须通过调用defaultWriteObject()方法来写入
*对象的描述以及那些可以被序列化的字段
*/
out.defaultWriteObject();
out.writeDouble(point.getX());
out.writeDouble(point.getY());
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
/**
*必须调用defaultReadObject()方法
*/
in.defaultReadObject();
double x = in.readDouble() + 1.0;
double y = in.readDouble() + 1.0;
point = new Point2D.Double(x, y);
}
public String toString()
{
return getClass().getName()
+ "[label = "+ label
+ ", point.getX() = "+ point.getX()
+ ", point.getY() = "+ point.getY()
+ "]";
}
private String label;
transient private Point2D.Double point;
}
import java.io.*;
import java.awt.geom.*;
public class TransientTest
{
public static void main(String[] args)
{
LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00);
try
{
System.out.println(label);//写入前
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("Label.txt"));
out.writeObject(label);
out.close();
System.out.println(label);//写入后
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("Label.txt"));
LabeledPoint label1 = (LabeledPoint)in.readObject();
in.close();
System.out.println(label1);//读出并加1.0后
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
class LabeledPoint implements Serializable
{
public LabeledPoint(String str, double x, double y)
{
label = str;
point = new Point2D.Double(x, y);
}
private void writeObject(ObjectOutputStream out) throws IOException
{
/**
*必须通过调用defaultWriteObject()方法来写入
*对象的描述以及那些可以被序列化的字段
*/
out.defaultWriteObject();
out.writeDouble(point.getX());
out.writeDouble(point.getY());
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
/**
*必须调用defaultReadObject()方法
*/
in.defaultReadObject();
double x = in.readDouble() + 1.0;
double y = in.readDouble() + 1.0;
point = new Point2D.Double(x, y);
}
public String toString()
{
return getClass().getName()
+ "[label = "+ label
+ ", point.getX() = "+ point.getX()
+ ", point.getY() = "+ point.getY()
+ "]";
}
private String label;
transient private Point2D.Double point;
}
为什么不是所有的类都序列化?
很重要的一个原因就是为了安全,java的类安全机制是做的很好的.
对于一个你要传输的对象,比如写到文件,或者进行rmi传输等等,在传输的过程中,
这个对象的private等域是不受保护的.
还有就是一些资源分配的问题,比如thread,序列化是很难对他重新分配资源,
所以并非所有的类都可以序列化.
有哪位大侠深入浅出的讲一件深层次的东西。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kky2010_110/archive/2009/11/20/4839807.aspx
发表评论
-
ISO-8859_1统一编码 java
2011-08-19 11:07 2036Java中文问题一直困扰着很多初学者,如果了解了Java系统的 ... -
UTF-8 GBK UTF8 GB2312
2011-08-19 10:46 1934UTF-8:Unicode TransformationFor ... -
Properties 类读取配置文件
2011-08-17 22:37 14651、使用java.util.Properties类的load( ... -
Java编程之四大名著
2011-08-06 10:07 1466中文第四版 http://download.csdn.n ... -
JDK5.0 新特性
2011-07-28 20:02 13921.AutoBoxing 原来int是非 ... -
JDK6的新特性
2011-07-28 19:57 1788JDK6的新特性 JDK6的新特性之一_Desktop类和Sy ... -
线程同步
2011-07-25 11:34 1281作者 : buaawhl http://www.iteye.c ... -
ZipInputStream类
2011-07-22 11:33 18777《Java开发实战经典》第12章Java IO,Java ... -
String、StringBuffer和StringBuilder的区别
2011-07-14 15:04 1373String是不可变的,StringBuffer是可变的;St ... -
精通JAVA核心技术
2011-07-11 11:31 1290http://www.2cto.com/ebook/20100 ... -
Java多线程sleep(),join(),interrupt(),wait(),notify()
2011-07-06 22:51 4918浅析 Java Thread.join() 一、在研究j ... -
FileInputStream/FileOutputStream的应用
2011-07-06 15:06 1416这是一对继承于InputStream和OutputStream ... -
Java基础之理解JNI原理
2011-07-05 14:55 1318JNI是JAVA标准平台中的一个重要功能,它弥补了JAVA ... -
面向对象和面向过程的区别
2011-07-04 09:52 1413面向过程就是分析出解 ... -
Java参数传值还是传引用
2011-07-03 20:52 3642参数是按值而不是按 ... -
JAVA排序汇总
2011-06-29 18:07 1510package com.softeem.jbs.lesson4 ... -
Java流操作,InputStream、OutputStream及子类FileInputStream、FileOutputStream;BufferedInpu
2011-06-27 18:09 19258Java将数据于目的地及来 ... -
线程综合文章
2011-06-27 10:48 1121http://lavasoft.blog.51cto.com/ ... -
由Java中的Set,List,Map引出的排序技巧
2011-06-24 14:18 2387一。关于概念: ... -
Date、String、Timestamp之间的转换
2011-03-20 16:59 2423public static Timestamp pars ...
相关推荐
1. **序列化标识符(SerialVersionUID)**:Java允许你为每个可序列化的类定义一个唯一的`serialVersionUID`,默认是由JVM根据类的结构计算出来的。如果类的版本更新导致结构变化,而此值未做更新,反序列化时会抛出`...
Java反序列化是一种将已序列化的对象状态转换回对象的过程,它是Java平台中持久化数据的一种常见方式。在Java应用程序中,序列化用于保存对象的状态以便稍后恢复,或者在网络间传输对象。然而,这个过程也可能引入...
Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在 Java 中,序列化和反序列化是...
在Java中,序列化(Serialization)指的是将对象的状态转化为字节流的过程,这一过程通常用于存储对象或者在网络中传输对象。相反地,反序列化(Deserialization)则是将字节流还原成对象的过程。这两种操作对于实现...
而在Java中,我们可以通过实现`Serializable`接口来使类支持序列化,或者使用`java.io.ObjectOutputStream`和`java.io.ObjectInputStream`进行对象的序列化和反序列化。 接下来,我们讨论反序列化。反序列化是序列...
4. **替代方案**:Java序列化并不是唯一的选择。例如,JSON、XML、protobuf等轻量级序列化库提供了更高效、更安全的数据交换方式。 为了克服这些问题,开发者可以考虑使用第三方序列化库,如Google的Protocol ...
**一、Java序列化** 1. **什么是序列化**:序列化是将对象的状态(属性和成员变量)转换为可以存储或传输的数据格式的过程。在Java中,通常是将对象转换为字节数组,以便写入磁盘或通过网络发送。 2. **为什么需要...
将需要被序列化的类实现 Serializable 接口,然后使用一个输出流(如:FileOutputStream)来构造一个 ObjectOutputStream 对象,接着,使用 ObjectOutputStream 对象的 writeObject(Object obj) 方法就可以将参数为 ...
Java序列化是将Java对象转换为字节流的过程,以便可以存储在磁盘上或通过网络进行传输。这个过程对于持久化对象数据、跨进程通信和在网络上传输对象非常有用。在Java中,序列化是通过实现`Serializable`接口来完成的...
Java序列化是Java平台中的一种标准机制,允许将对象的状态转换为字节流,以便存储在磁盘上、通过网络进行传输或者在某些时候恢复原来的对象状态。这一过程包括两个主要步骤:对象的序列化(将对象转换为字节流)和反...
Java序列化是Java平台中的一种标准机制,允许对象的状态被保存到磁盘或者在网络中进行传输,以便在后续的时间或地点恢复这些对象。这个过程包括两个主要操作:序列化(将对象转换为字节流)和反序列化(将字节流恢复...
1. **定义**: Java对象序列化是将Java对象转换为字节流的过程,以便可以存储在磁盘上或在网络上传输。它允许我们将对象的状态保存下来,即使程序关闭,下次启动时也能恢复到之前的状态。 2. **接口**: 实现序列化的...
Java序列化标准定义了一套规则来描述如何将Java对象转换为可以被序列化的形式。 **1.2 写入对象流** 当一个对象被写入对象流时,它的状态会被编码为一个字节序列。这一过程由`ObjectOutputStream`类完成。`...
Java序列化机制的优点在于它提供了一种标准的方式来处理对象的持久化和在网络间的传输。然而,序列化也存在安全风险,比如序列化可能导致远程代码执行攻击。因此,对于敏感信息或复杂对象结构,应谨慎使用序列化,并...
Java 序列化机制 Java 序列化是将一个对象的状态写入一个 Byte 流里,并且可以从其它地方把该 Byte 流里的数据读出来,重新构造一个相同的对象。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到...
二、为什么需要Java序列化 1. 持久化:序列化可以将对象状态持久化到磁盘,以便下次程序运行时可以恢复。 2. 网络传输:在分布式系统中,序列化对象可以方便地在网络间进行传输。 3. 缓存:序列化有助于将对象存储在...
Java序列化默认会序列化对象的所有属性,但可以通过以下两种方式排除指定属性: - **使用`transient`关键字**:在要排除的属性前添加`transient`关键字。例如: ```java public class MyClass implements ...
Xson是一个Java对象序列化和反序列化程序。支持Java对象到字节数组的序列化,和从字节数组到Java对象的反序列化。 Maven: <groupId>com.github.xsonorg</groupId> <artifactId>xson-core <version>1.0.1 ...
### Java序列化(Serializable)的作用与反序列化详解 #### 一、序列化的概念 序列化是指将程序中的对象转换为一系列字节流的过程,主要用于保存对象的状态或在网络之间传输对象。序列化的主要目的是为了能够持久化...
Java序列化是Java平台中的一种核心机制,它允许对象的状态被转换成字节流,以便存储到磁盘、数据库,或者在网络中进行传输。这对于实现持久化、远程方法调用(RMI)以及Enterprise JavaBeans(EJB)等高级功能至关...