java 中类为啥要序列化

java里为什么要序列化?http://zhidao.baidu.com/link?url=7_wAQ8eAl28vcJPE5OKM5Y0Bo4aINNQokHhRmI9XPszEoTO5QF-gNbOTHPzU4e8JMxQ2FYFjU5kuUgtSIPYYN_
2013-06-19 09:57轻风晓雪 | 浏览 2276 次
 编程语言java
1不序列化是二进制流,序列化也是二进制流,有什么不同?最后在计算机里不都是0和1保存嘛?还是说不序列化也可以恶保存,就是没有序列化保存的后好什么的?

2比如我写记事本里写了一篇文章,这里有对象吗?全都是文字啊,那我保存为文本文件的时候,也要序列化一下?然后我以后打开这个文本文件读取到内存,还要反序列化?

3比如实现购物信息记录的保存,不是要序列化吗,序列化以后保存的是文本文件还是什么文件,能用记事本打开看到文字的记录信息吗,不是说序列化后是字节流吗,那文本文件是字符流,那记录信息打开后应该是乱码才对啊,因为序列化后是字节流的!文本文件打开自然就是乱码了?

就不要说什么是序列化的概念什么了,我都看过好几遍了,说是为了保存对象结构什么的,但是还不是很理解,对于普通的字符串或者不序列化之间有何不同,还没明白,尽量用例子或者大白话给讲讲,不要太专业,通俗易懂就可以了
分享到:
2013-06-19 10:14 再不玩“疯狂攀岩”你就OUT啦! 提问者采纳
楼主的问题很有意思,不过你对序列化和反序列的应用场景搞错了,我们说的序列化和反序列化是对JAVA而言(其他面向对象语言可能也有)的,序列化的实体是个对象,结果也是个对象,并非是格式化文本,你在记事本里看到的购物信息保存记录,其实不是对象序列化的结果,而是对象输出的格式化文本,真正的序列化对象是看不懂的。

在实际使用对象序列化时,一种应用场景是将对象序列化到持久化存储(本地硬盘),我们此时不想做文件解析,也不想有人读懂这个持久化文件,当我们需要时,可以直接采用反序列化将保存的文件生成为对象;另一种应用场景是在网络传输过程中,此时对象会在不同主机上传播,序列化会将对象转成码流由对端进行解析,这个解析过程不需要人参与。

普通字符串是经过解析后的对象,有对象到字符串要加入解析逻辑,人才能看懂。
序列化的结果是个只有JAVA虚拟机认识的文件,人不参与,只是用于保存对象或传输。

解决你的问题了么?
追问:
序列化和购物信息记录里的字符串有关系吗?比如我不序列化,这些字就不能保存到硬盘了吗?

还一个就是序列化以后保存的对象在哪里啊,是购物信息记录里面的文字吗?都一起保存到硬盘上面了?还是放哪里,比如我打开购物信息记录里面只有:某某于某天购物等等,这里面哪有对象啊,跟看文本文件没区别啊,那咱们老说保存对象对象的 我不明白这个对象到底在哪里,和字符串有什么关系没
追答:
序列化和字符串没有关系。

字符串是对象里的某些数据的输出结果,你看到的文本文件只包含了对象的一部分信息,你看到可能只是个值而已。

比如一个对象
object monkey
{
    String monkeyName = "悟空";

    long monkeyAge = 1000;

}

你输出的字符串可能只是这个:

悟空;
10000;

但对象很多信息丢掉了,比如对象名称,字段属性之类的。

序列化时把对象完整的输入到某个地方,比如文件,这个文件人类是看不懂的,但在反序列化时,文件就会被完成的读取为一个对象,和上面的对象一模一样,这样我们就可以在代码中对对象进行直接操作了。

are we clear?
追问:
good!,原来如此,但是另一个问题又来了,对象保存在哪里?是跟我的文本文件一起保存到硬盘里吗?比如我的文本里字符串是5个字符串文字,按一个字符是2字节,大小是10字节,那如果按你的说法,把字段 名称也保持了,那文件的内容会增多,那有可能不是10字节了,因为你还保存了字段 属性名什么的,那岂不是多占我硬盘空间了?
追答:
保存在哪里是你控制的,你想输出到文件系统也可以,其他地方也行。

你说的大小我不知道跟什么比较,一般情况下肯定会比只保存字符串要大,毕竟有其他的信息需要存储。

会多占你些空间,但比起你手动反序列化这些成本还是值得的。
追问:
我的意思是说,你序列化以后保存的对象内容,是不是也在最终产生的文本文件里?
比如生成了一个购物信息记录.txt的文件,这里面假如有购物信息这4个文字,那对象能在文本里看到吗?还是只能看到字符串?保存的对象其实也在这个文件里,但是不会输出显示,而且最重要的是文件的大小在电脑里还是显示4个字符的大小,但是对象它也是存在的也占硬盘空间,只不过系统只显示字符串的大小而已?
追答:
文本文件是用来保存文本的,是你在代码里控制生成txt。

对象序列化生成的序列化文件,跟txt文件没有关系,你序列化之后存成什么样的文件格式,存储到什么位置,是自己控制的。

你不应该认为txt存储对象,txt存储的只能是文本,对象序列化的结果是一个序列化文件,是一个文件输出流的结果。
追问:
序列化文件保存在哪,我想见识见识,保存在电脑的哪个角落里?我看看跟文本文件有啥不一样的
追答:
import java.io.Serializable;

import java.io.*;

public class Cat implements Serializable {
private String name;

public Cat() {
this.name = "new cat";
}

public String getName() {
return this.name;
}

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

public static void main(String[] args) {
Cat cat = new Cat();
try {
FileOutputStream fos = new FileOutputStream("catDemo.out"); //这就是你序列化文件的存储位置,是由自己控制的
ObjectOutputStream oos = new ObjectOutputStream(fos);
System.out.println(" 1> " + cat.getName());
cat.setName("My Cat");
oos.writeObject(cat);
oos.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
try {
FileInputStream fis = new FileInputStream("catDemo.out");
ObjectInputStream ois = new ObjectInputStream(fis);
cat = (Cat) ois.readObject();
System.out.println(" 2> " + cat.getName());
ois.close();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}

输出内容:

catDemo.out大小:0.06K
 已经过百度安全检测,放心下载
点击下载
下载量:53
追问:
原来.out文件就是序列化后的文件啊,那保存的购物信息记录也全在这里面吗?如果是在这里,那这个文件不是.txt格式的,打开看肯定是乱码?

如果信息记录没在out文件里,那应该在指定一个路径保存为.txt文件格式吧?这个就是能打开看的信息记录?

这俩文件是分开的 还是合在一起的?
追答:
保存的购物信息都在catDemo.out中,但你是看不懂的,要JAVA虚拟机才能看懂,因为序列化文件本身不是为人类阅读准备的。

如果你想输出为txt,需要你在程序中手动指定输出的内容和格式,这样你才能够看懂。

不是两个文件,也可能是多个文件,你想生成多少文件就生成多少文件。
追问:
那在问下,如果我也想保存输出为txt格式的。在程序中手动添加一个路径为:购物信息.txt就行了是吗?那你上面的那个catDemo.out不用删掉继续保留?

这样在电脑里就会产生一个是catDemo.out文件,一个是文本格式的购物信息.txt?
catDemo.out已经是序列化保存了一次了,后面再输出的.txt不需要序列化了,直接输出字符流保存到电脑里即可?因为前面已经有一个序列化了
追答:
对的,你可以这样理解。

另外你是否需要序列化看你自己的需求,序列化是为了程序读取方便,没有必要非得输出的。
追问:
意思就是说,你要不序列化也行,就是程序读取不方便,而且以前在内存里的对象结构全都没有了?
上面那个还要问下,其实在catDemo.out文件里只包含对象信息,应该也包含字符串信息吧?就是应该也包含txt里面的购物信息,而我输出txt格式,只是从catDemo.out文件里提取出字符串部分的信息给用户看而已,实际对象内容还在catDemo.out里保存?
追答:
序列化是一种操作,你做序列化不是必要的,你做序列化是因为你想保存这个对象在文件系统上。

想象一种场景:
你开发了一个游戏,游戏里有人物,人物里有个属性时他现在拥有的金钱,当用户玩到一半选择保存游戏时,你有两个方案:
保存用户的金钱到txt中,下次加载游戏的时候,再从txt中读取金钱,让用户接着玩。
进行对象序列化,把对象存到文件系统上,下次可以玩的时候使用反序列化加载。
但是第一种方案有个缺点,用户如果知道了txt中保存着金钱,就可以自己把金钱改成99999,采用对象序列化方式就不会了。

最后一个,你没有理解JAVA中的对象,对象是在内存中保存的,它不会因为你序列化了之后它就不存在了,序列化等于把对象的数据复制了一份,序列化,然后输出到文件系统,真正的对象还是在程序中的。

就像你玩游戏玩到一半,突然想存个档,然后就把对象序列化了,但是游戏还在继续啊,里面的人物也没死啊,说明人这个对象还是在内存中存在的。

are we clear?
提问者评价
谢谢!
评论(11) | 77 0

babyly1314 | 四级 采纳率71%
擅长: 电脑装机/选购 JAVA相关 服务器软件 架构设计 汽车购买
其他类似问题
2010-08-14什么是java序列化,如何实现java序列化?18
2010-12-06java中为什么要序列化?什么时候序列化。42
2012-02-19Java中为什么要序列化?什么时候用到序列化?61
2008-05-13关于java序列化的问题27
2010-12-22什么是序列化,在java中如何实现序列化。40
更多关于java 中类为啥要序列化的问题>>
2013-06-19 10:23 网友采纳
你知道什么叫 序列化  吗?
你知道序列化的作用吗?
你可以把序列化,实现Serializable 接口,是序列化了的类告知该程序,这个类的对象可以读写。
读写不仅仅是在文本中读写该类,还可以通过别的流来进行读写。
没有序列化的类,是不能形成二进制读写流。
如果你随便敲写文字进去一个记事本里面。这个就不是序列化的范围了。序列化是指类对象的。你能确保你自己敲上去的文字就是类的对象了吗?你能确保你敲上去的是什么类的对象吗?
第三个问题,已经没有必要解释了。你要知道序列化是什么东西,你就不会问这问题
评论 | 3 4

Stale331x | 来自团队:Java乐园 | 十级 采纳率47%
擅长: JAVA相关 数据结构及算法 数据库DB 服务器软件
为您推荐:
按默认排序 | 按时间排序
其他3条回答
2013-06-19 10:31 zqhmfk | 五级
要使得javabean能够通过I/O在网络传输那么就必须实现Serializable接口,这是一种规范,就相当于你要tomcat调用你的servlet你必须实现它的接口一样。
要解释你的疑问就说说流吧:
首先流分为:字节流(Inputstream)、字符流(Reader),而你说的文件那就属于FileInputStream属于字节流,而你说的对象那就是ObjectInputStream也属于字节流,但是写对象必须实现Serializabled接口(这是API文档原话:只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。)
追问:
FileInputStream属于字节流,这也是字节流,是不是说如果我保存的不是对象,可以用这个流?可是java里好像都有对象啊,那就都只能用ObjectInputStream流?

那保存的购物记录是文本文件啊,打开能看到里面的文字信息,也没看到有对象啊,那序列化保存的对象在哪里啊,也在购物记录里吗,一起保存到硬盘里去了?
追答:
文本文件属于字符流(Reader),让你看下API文档原话你就明白了:FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream。

大哥还在纠结啊。。。

我最后就给你讲一个大家熟悉的一个例子
大家都用过web容器吧,现在就说weblogic
假如我们要去注册帐号,我们是先进入注册页面,把必填的都填完,最后点击注册按钮ok
此时客户端就发送了一个request注册的请求,
1客户端先把用户填写的信息保存在该请求中-------------------------------客户端
2然后把该请求request对象序列化,request对象保存了用户填写的注册信息
Socket socket=new Socket("ip",10000);
 ObjectOutputStream oos1 = new ObjectOutputStream(socket.getOutputStream());
FileOutputStream out = new FileOutputStream("file.object"); //楼主看看跟文本文件有啥不一样的ObjectOutputStream oos2 = new ObjectOutputStream(out);
oos1.writeObject(request); //楼主要看序列化是怎么样的加这句
oos2.writeObject(request);
oos.close();
3然后服务器也就是weblogic接收该请求,进行反序列化-----------------------------服务器
ServerSocket ss=new ServerSocket(10000);
   while(true){
    socket=ss.accept();
        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                Request request= (Request) ois.readObject();
        ois.close();

}

写的好累啊。。。望楼主采纳!!!
评论 | 4 0
2013-06-19 10:11 testhdg | 四级
以前我也不理解,不过现在我已经理解了:
是这样的,如果JAVA的对象要保存到硬盘或者要传输,必须实现Serializable接口,则这个接口,里面什么方法都没,它只是一个标识,而且,最好有一个序列的版本号,如private static final long serialVersionUID = 1L;以前我做过实验,我写了一个类Person,然后Person p=new Person();通过序列化,我用代码把p这个对象,保存在文件文件里了!不序列化,绝对不可能保存在计算机硬盘里!
追问:
那文本文件打开后是不是只能看到字符串,看不见保存的对象信息?但是这个文件里面确实有对象信息,只不过系统不给你显示出来,只显示字符串内容而已?而且这个文件实际大小应该是字符串大小+对象大小,但是系统一样只显示文本信息的字符串大小?

是这么理解吧?
追答:
我用代码把p这个对象,保存在文件文件里后,打开看了,不像乱码,但又像乱码的东西。你说得对,只能看到字符串,看不见保存的对象信息,但,你用代码处理后,就可以看见保存的对象信息了。要自己写代码处理,当初怎么写,就反过来,就可以显示对象的信息了。大小与你的对象个数有关,我那时也做了试验,我循环写10与10000次,大小就不一样了。文件大小,不好说,应该只与对象有关,哪来的什么字符串。代码是别人帮我写字,但忘记在哪了,不然,贴出来给你,你就理解了。
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。
是对象永久化的一种机制。
   确切的说应该是对象的序列化,一般程序在运行时,产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象(因为是对象,所以有各自不同的特性)保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取这些对象的值,或者在其他程序中利用这些保存下来的对象。这种情况下就要用到对象的序列化。
   只有序列化的对象才可以存储在存储设备上。为了对象的序列化而需要继承的接口也只是一个象征性的接口而已,也就是说继承这个接口说明这个对象可以被序列化了,没有其他的目的。之所以需要对象序列化,是因为有时候对象需要在网络上传输,传输的时候需要这种序列化处理,从服务器硬盘上把序列化的对象取出,然后通过网络传到客户端,再由客户端把序列化的对象读入内存,执行相应的处理。
   对象序列化是java的一个特征,通过该特征可以将对象写作一组字节码,当在其他位置读到这些字节码时,可以依此创建一个新的对象,而且新对象的状态与原对象完全相同。为了实现对象序列化,要求必须能够访问类的私有变量,从而保证对象状态能够正确的得以保存和恢复。相应的,对象序列化API能够在对象重建时,将这些值还原给私有的数据成员。这是对java语言访问权限的挑战。通常用在服务器客户端的对象交换上面,另外就是在本机的存储。
   对象序列化的最主要的用处就是在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口
				
时间: 2024-10-16 07:57:24

java 中类为啥要序列化的相关文章

Java实现对象的序列化

什么是对象的序列化? 序列化:把对象转化成字节序列的过程就是对象的序列化:反序列化:把字节序列转化成对象的过程就是对象的反序列化.单看概念比较抽象,但是看代码就会明白. 对象序列化的用途 1.Java程序在运行中,对象都是分配在内存中,而序列化的一个用途就是将内存的中对象转化成磁盘中的对象. 2.对象不能直接在网络中传输,有时候需要将对象转成字节序列在网络中传输,这就是对象序列化的第二个用途. 如何实现对象的序列化? 1.新建一个实体对象,实现Serializable接口,这个实体对象就可以进行

Java中的对象序列化

好久没翻译simple java了,睡前来一发.译文链接:http://www.programcreek.com/2014/01/java-serialization/ 什么是对象序列化 在Java中,对象序列化指的是将对象用字节序列的形式表示,这些字节序列包含了对象的数据和信息,一个序列化后的对象可以被写到数据库或文件中,并且支持从数据库或文件中反序列化,从而在内存中重建对象: 为什么需要序列化 序列化经常被用于对象的网络传输或本地存储.网络基础设施和硬盘只能识别位和字节信息,而不能识别Jav

浅谈Java中类的继承

继承作为面向对象的三大基本特征之一,也是Java中必不可少的组成部分.因此,Java中类的继承和其他面向对象语言的继承都是大同小异的. 继承的优点: 通过继承可以简化类的定义. Java只支持单继承,不允许多重继承. 可以有多承继承,即一个类可以继承某个类的子类,如类B继承了类A,类C又继承了类B,那么C也间接的继承了A. 子类继承所有父类的成员变量和成员方法,但不继承父类的构造方法.在子类的构造方法中,可使用语句super(参数列表)调用父类的构造方法. 如果子类的构造方法中没有显性的调用父类

再谈Java中类的继承

上篇博客谈到了Java中类的继承,但是那些远远不能满足我们在实际操作中的需要,那么怎么才能让子类的功能更强大,并且具有父类的属性呢? 一: 父类 1 public class A { 2 3 final String name="A"; 4 5 void A1(){}; 6 } 子类 1 public class AA extends A{ 2 3 String name="AA"; 4 5 void AA1(){}; 6 7 public static void

java Serializable和Externalizable序列化反序列化详解--转

一.什么是序列化? “对象序列化”(Object Serialization)是 Java1.1就开始有的特性. 简单地说,就是可以将一个对象(标志对象的类型)及其状态转换为字节码,保存起来(可以保存在数据库,内存,文件等),然后可以在适当的时候再将其状态恢复(也就是反序列化).serialization 不但可以在本机做,而且可以经由网络操作.它自动屏蔽了操作系统的差异,字节顺序等.比如,在 Windows 平台生成一个对象并序列化之,然后通过网络传到一台 Unix 机器上,然后可以在这台Un

JAVA与JSON的序列化、反序列化

package com.linkage.app.memcache; import java.util.HashMap;import java.util.Map.Entry; import net.sf.ezmorph.Morpher;import net.sf.ezmorph.MorpherRegistry;import net.sf.ezmorph.bean.BeanMorpher;import net.sf.json.JSONObject;import net.sf.json.util.JS

动车上的书摘-java对象流与序列化

动车上的书摘-java对象流与序列化 摘要: 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 钢笔不限贵便宜,书法是来自心对手的交流.-泥沙砖瓦浆木匠 一.对象序列化 当需要存储相同类型的数据,选择固定的长度记录是好选择.但是在面向对象(OOP)程序中,对象之间很少有全部相同的类型.所以,java语言支持一种称为对象序列化(object serialization)的机制. 下面展示一个序列化例子,关于两个对象 Em

java中类的生命周期

在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM.在程序执行中JVM通过装载,链接,初始化这3个步骤完成. 类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象.用来封装数据.但是同一个类只会被类装载器装载以前 链接就是把二进制数据组装为可以运行的状态.   链接分为校验,准备,解析这3个阶段 校验一般用来确认此二进制文件是否适合当前的JVM(版本), 准备就是为静态成员

Java中类的加载、连接和初始化

Java中类的加载.连接和初始化 类的加载.连接和初始化 先介绍一下JVM和类 JVM和类: 当我们调用Java命令运行某个Java程序时,该命令将会启动一个Java虚拟机进程,不管该Java程序有多么复杂,该程序启动的所有线程,所有变量都处于该Java虚拟机进程里,它们都使用该JVM进程的内存区.当系统出现以下几种情况时,JVM进程将被终止. 1.       程序运行到最后正常结束: 2.       程序运行到使用System.exit()或Runtime.getRuntime().exi