java编程思想阅读笔记(十)I/O系统(下)

原创 2012年03月30日 14:31:45
    补充下对象序列化的相关内容。至于XML读写之类的就不写了,无非也就是按照规定方式读写的东西。
    对象的序列化将那些实现了Serializable(Externalizable)接口的对象转换成一个字节序列,并能在以后将这字节序列完全恢复为原来的对象;说得白话些就是将对象相关的信息保存起来(可以写到文件里,或者远程发送出去),在需要的时候把这些保存的信息再恢复出来形成对象;这里就会有下面一些问题:
    1.保存了完整的对象信息了吗?
    对象的序列化的字节序列中,保存了对象的数据成员(属性),同时也包括了其成员所引用的信息;在恢复过程中不需要调用任何构造器;那么经过远程传输为什么却不可以直接恢复,原因是需要用到起class对象信息,看一下简单的用法:
    ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(""));
    out.writeObject(duixiang);

    ObjectInputStream in = new ObjectInputStream( new FileInputStream(""));
    (类型)in.readObject();
    这是一个简单的将对象序列化到文件中,然后读取文件再恢复的过程;不难理解如果是不同程序之间对象的恢复,至少得有这个对象的类型信息啊。
    2.有些成员不想保存当前信息
    对于序列化的控制,可以使用Externalizable接口,通过writeExternal()  readExternal()方法来做。这个在序列化时通过将当前信息在writeExterna方法中保存想要保存的信息,恢复时,调用默认的构造器之后,通过readExternal方法将保存的信息恢复出来。这里就看到与实现Serializable接口的区别,一个不需要调用任何的构造器,一个调用默认的构造器。
    那么如果想用到Serializable的自动化,又不想保存部分成员信息呢,可以使用transient关键字:
    private transient string password;
    3.对于引用的分歧
    如果序列化多个对象,而都引用了一个对象,那么这个对象在恢复的时候是有不同的副本还是只有一个存储地址?通过下面的例子可以看到:
package com.test.myjava;

//主要演示了Serializable接口以及transient关键字
import java.io.*;
class Information implements Serializable{}
public class SerializableTest implements Serializable{
	private int id;
	private transient String password;
	private String name;
	private Information otherInformation;
	public SerializableTest(int i,String p,String n,Information f){
		System.out.println("Constructor:"+n);
		id = i;
		password = p;
		name = n;
		otherInformation = f;
	}
	public String toString(){
		return "id:"+id +" name:"+name +" pasword:"+password //密码没有保存,为null
		          +" friendName:"+otherInformation;//otherInformation.hashCode() 
	}
	public static void main(String[] args ) throws IOException,ClassNotFoundException{
		Information allFriendName = new Information();

		SerializableTest user1 = new SerializableTest(1,"1","user1",allFriendName);
		SerializableTest user2 = new SerializableTest(2,"2","user2",allFriendName);
		SerializableTest user3 = new SerializableTest(3,"3","user3",allFriendName);
		
		System.out.println("Start\n");
		System.out.println(user1.toString());
		System.out.println(user2.toString());
		System.out.println(user3.toString());
		//序列化
		ByteArrayOutputStream buf1 = new ByteArrayOutputStream();
		ObjectOutputStream out1 = new ObjectOutputStream(buf1);
		out1.writeObject(user1);
		out1.writeObject(user2);
		
		ByteArrayOutputStream buf2 = new ByteArrayOutputStream();
		ObjectOutputStream out2 = new ObjectOutputStream(buf2);
		out2.writeObject(user3);
		//恢复
		ObjectInputStream in1 = new ObjectInputStream(
				new ByteArrayInputStream(buf1.toByteArray()));
		ObjectInputStream in2 = new ObjectInputStream(
				new ByteArrayInputStream(buf2.toByteArray()));
		user1 = (SerializableTest)in1.readObject();
		user2 = (SerializableTest)in1.readObject();
		user3 = (SerializableTest)in2.readObject();
		
		System.out.println("Then\n");
		System.out.println(user1.toString());
		System.out.println(user2.toString());
		System.out.println(user3.toString());

	}
}

输出结果:

Constructor:user1
Constructor:user2
Constructor:user3
Start

id:1 name:user1 pasword:1 friendName:com.test.myjava.Information@c17164
id:2 name:user2 pasword:2 friendName:com.test.myjava.Information@c17164
id:3 name:user3 pasword:3 friendName:com.test.myjava.Information@c17164
Then

id:1 name:user1 pasword:null friendName:com.test.myjava.Information@19b49e6
id:2 name:user2 pasword:null friendName:com.test.myjava.Information@19b49e6
id:3 name:user3 pasword:null friendName:com.test.myjava.Information@10d448

    对于写到一个流中的引用,确实都指向一个地址,而对于不同的流则有不同的副本。
版权声明:本文为博主原创文章,转载请注明出处。

相关文章推荐

java编程思想阅读笔记(十)I/O系统(上)

又是好久没有更新了,在外面出差,还参加了个Nice公司的亚太区销售峰会,体会了些软件卖钱的理念,然后就是公司搞得气派与自己英文的太烂了。最后说书,这个书其实第一遍算是看个差不多了,慢慢的在把笔记补上,...

转载《Java编程思想》Java I/O系统章节阅读笔记

今天正好要写个小程序需要用到io操作,突然想起来java有个nio一直没用过,就找了点资料研究了一下,顺便做点笔记,以便日后查阅。 ---------------------------------...

java编程思想读书笔记 第十八章 java I/O系统(第三篇)

1. 文件读写的工具 一一个很常见的程序化的任务就是读取文件到内存,修改,然后再写出。java I/O类库的问题之一就是:它需要编写相当多的代码去执行这些常用的工作–没有任何基本的帮助功能可以为我们...

java编程思想读书笔记 第十八章 java I/O系统(第五篇)

1. 压缩 压缩要注意的: 1)压缩类库是按字节方式而不是字符方式处理的; 2)尽管存在许多种压缩算法,但是Zip和GZIP是最常用; 3)Zip压缩和GZIP的区别:GZIP接口非常简单,适...

java编程思想读书笔记 第十八章 java I/O系统(第二篇)

1.添加属性和有用的接口FilterInputStream和FilterOutputStream是用来提供装饰器类接口的以控制特定输入流和输出流的两个类。FilterInputStream和Filte...

《Java编程思想》之I/O系统

1、Java中“流“类库让人迷惑的主要原因:创建单一的结果流,却需要创建多个对象。 2、使用层叠的数个对象为单个对象动态地、透明地添加职责的方式,称作“修饰器“模式。修饰器必须与其所修饰的对象具有相...

java编程思想读书笔记 第十八章 java I/O系统(第四篇 新I/O)

新的I/OJDK1.4的java.nio.*包中引入了新的javaI/O类库,其目的在于提高速度,旧的I/O包已经使用nio重新实现过,以便充分利用这种速度提高。因此,即便我们不显示的使用nio编写代...

《Java编程思想第四版》笔记---18章(4) I/O 流式部分--管道流与对象流

管道流          管道流主要用于连接两个线程的通信。 管道流也分为字节流(PipedInputStream、PipedOutputStream)和字符流(PipedReader、...

《Java编程思想》学习笔记14——I/O高级

1.内存映射文件: 内存映射文件允许把比内存大的文件读入内存中创建和修改,使用内存映射文件,可以像使用内存中数组一样在内存中访问整个文件,例子如下: [java] view p...

《Java编程思想第四版》笔记---18章(2) I/O 非流式部分

非流式部分 File类       在Java语言的java.io包中,由File类提供了描述文件和目录的操作与管理方法。但File类不是InputStream、OutputStream或Read...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java编程思想阅读笔记(十)I/O系统(下)
举报原因:
原因补充:

(最多只允许输入30个字)