java uml 为什么_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虚拟机认识的文件,人不参与,只是用于保存对象或传输。

解决你的问题了么?

追问:

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

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

追答:

序列化和字符串没有关系。

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

比如一个对象objectmonkey

{

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 classCat implements Serializable {privateString name;publicCat() {this.name = "new cat";

}publicString getName() {return this.name;

}public voidsetName(String name) {this.name =name;

}public static voidmain(String[] args) {

Cat cat= newCat();try{

FileOutputStream fos= new FileOutputStream("catDemo.out"); //这就是你序列化文件的存储位置,是由自己控制的

ObjectOutputStream oos = newObjectOutputStream(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= newObjectInputStream(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 0babyly1314| 四级 采纳率71%擅长: 电脑装机/选购 JAVA相关 服务器软件 架构设计 汽车购买

其他类似问题2010-08-14什么是java序列化,如何实现java序列化?18

2010-12-06java中为什么要序列化?什么时候序列化。42

2012-02-19Java中为什么要序列化?什么时候用到序列化?61

2008-05-13关于java序列化的问题272010-12-22什么是序列化,在java中如何实现序列化。40更多关于java 中类为啥要序列化的问题>>

2013-06-19 10:23网友采纳

你知道什么叫 序列化 吗?

你知道序列化的作用吗?

你可以把序列化,实现Serializable 接口,是序列化了的类告知该程序,这个类的对象可以读写。

读写不仅仅是在文本中读写该类,还可以通过别的流来进行读写。

没有序列化的类,是不能形成二进制读写流。

如果你随便敲写文字进去一个记事本里面。这个就不是序列化的范围了。序列化是指类对象的。你能确保你自己敲上去的文字就是类的对象了吗?你能确保你敲上去的是什么类的对象吗?

第三个问题,已经没有必要解释了。你要知道序列化是什么东西,你就不会问这问题

评论| 3 4Stale331x| 来自团队: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= newObjectOutputStream(socket.getOutputStream());

FileOutputStreamout = 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= newObjectInputStream(socket.getInputStream());

Request request=(Request) ois.readObject();

ois.close();

}

写的好累啊。。。望楼主采纳!!!

评论| 4 0

2013-06-19 10:11 testhdg |四级

以前我也不理解,不过现在我已经理解了:

是这样的,如果JAVA的对象要保存到硬盘或者要传输,必须实现Serializable接口,则这个接口,里面什么方法都没,它只是一个标识,而且,最好有一个序列的版本号,如privatestatic final long serialVersionUID = 1L;以前我做过实验,我写了一个类Person,然后Person p=newPerson();通过序列化,我用代码把p这个对象,保存在文件文件里了!不序列化,绝对不可能保存在计算机硬盘里!

追问:

那文本文件打开后是不是只能看到字符串,看不见保存的对象信息?但是这个文件里面确实有对象信息,只不过系统不给你显示出来,只显示字符串内容而已?而且这个文件实际大小应该是字符串大小+对象大小,但是系统一样只显示文本信息的字符串大小?

是这么理解吧?

追答:

我用代码把p这个对象,保存在文件文件里后,打开看了,不像乱码,但又像乱码的东西。你说得对,只能看到字符串,看不见保存的对象信息,但,你用代码处理后,就可以看见保存的对象信息了。要自己写代码处理,当初怎么写,就反过来,就可以显示对象的信息了。大小与你的对象个数有关,我那时也做了试验,我循环写10与10000次,大小就不一样了。文件大小,不好说,应该只与对象有关,哪来的什么字符串。代码是别人帮我写字,但忘记在哪了,不然,贴出来给你,你就理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值