1 1.Java 1.0 & 1.1 streams and classes 2.IO idioms 3. Object serialization.

49
1 1. Java 1.0 & 1.1 streams and classes 2. IO idioms 3. Object serialization

Transcript of 1 1.Java 1.0 & 1.1 streams and classes 2.IO idioms 3. Object serialization.

1

1. Java 1.0 & 1.1 streams and classes2. IO idioms3. Object serialization

2

Stream= I/O abstraction-for any source (input) or sink (output) of data-hiding data handling in I/O device

Java 1.0

Java 1.1

Input Output

Java 1.0 and 1.1 I/O systems not separate designsBoth systems are used in parallel

InputStream OutputStream

Reader Writer

3

InputStream

“Physical” source

1. Byte array (memory)2. String object (memory)3. File4. Pipe (for interprocess/inter thread communication)5. Sequence of streams6. Others (e.g. internet connection – sockets)

InputStream

Application

4

InputStream

1. Byte array (memory)2. String object (memory)3. File4. Pipe (for interprocess/inter thread communication)5. Sequence of streams6. Others (e.g. internet connection – sockets)

InputStream

StringBufferInputStream

FileInputStream

PipedInputStream

SequenceInputStream

ByteArrayInputStream

InputStream has poor interfaceUsually wrapped in FilterInputStream-object !

5

FilterInputStream

1. DataInputStream - read primitive types (readXXX())2. BufferedInputStream - add buffering to InputStream3. LineNumberInputStream - add line numbers to InputStream4. PushbackInputStream - add push back buffer to InputStream5. InflaterInputStream - decompress InputStream

Inherits from InputStream !

All FilterInputStreams are decorators- ADD functionality, keep same interface- can be “concatenated”

e.g. InputStream in + line numbers and reading primitives :DataInputStream d=new DataInputStream(new LineNumberInputStream(in));

6

Java1.0 Input classes

Adaptation to physical devices

InputStream

StringBufferInputStream

FileInputStream

PipedInputStream

SequenceInputStream

ByteArrayInputStream FilterInputStream

DataInputStream

BufferedInputStream

LineNumberInputStream

PushbackInputStream

Decorators

InflaterInputStream

7

OutputStream

“Physical” destination

1. Byte array (memory)2. File3. Pipe (for interprocess/inter thread communication)4. Others (e.g. internet connection – sockets)

OutputStream

Application

8

OutputStream

1. Byte array (memory)2. File3. Pipe (for interprocess/inter thread communication)4. Others (e.g. internet connection – sockets)

OutputStream

FileOutputStream

PipedOutputStream

ByteArrayOutputStream

OutputStream has poor interfaceUsually wrapped in FilterOutputStream-object !

9

FilterOutputStream

1. DataOutputStream - write primitive types (writeXXX()) (binary format – use with DataInputStream)

2. BufferedOutputStream - add buffering to OutputStream3. PrintStream - add formatting to OutputStream

(text format – for “display” human readable output)4. DeflaterOutputStream - add compression to OutputStream

Inherits from OutputStream !

Decorator pattern is used (again)

e.g. OutputStream out + buffering + primitives

DataOutputStream d = new DataOutputStream(new BufferedOutputStream(out));

10

Java1.0 Output classes

Adaptation to physical devices

OutputStream

FileOutputStream

PipedOutputStream

ByteArrayOutputStream FilterOutputStream

DataOutputStream

BufferedOutputStream

PrintStream

Decorators

DeflaterOutputStream

11

A simple examplePrimitive output

import java.io.*;

import java.util.*;

class PrimitiveIO {

public static void main(String[] args) {

int[] a={1,3,5,7};

try {

writeInt(a,"Test.dat");

int[] b=readInt("Test.dat");

for(int i=0;i<b.length;i++)

System.out.print("- "+b[i]);

} catch(IOException e) {

e.printStackTrace();

}

}

public static void writeInt(int[] a,String n) throws IOException {

DataOutputStream o=new DataOutputStream(new FileOutputStream(n));

for(int i=0;i<a.length;i++)

o.writeInt(a[i]);

o.close();

}

// .. Continued …

}

12

A simple examplePrimitive input

class PrimitiveIO {

// … continued …

public static int[] readInt(String n) throws IOException {

int[] res;

ArrayList l=new ArrayList();

DataInputStream in=new DataInputStream(new BufferedInputStream(new FileInputStream(n)));

try {

while(true) l.add(new Integer(in.readInt()));

} catch(EOFException e) {

System.out.println("End of file reached !");

} finally {

in.close();

}

res=new int[l.size()];

for(int i=0;i<l.size();i++) res[i]=((Integer)(l.get(i))).intValue();

return res;

}

}

13

Java1.1Main changes/additions

• InputStream/OutputStream -> byte oriented (“pure binary”) new classes Reader/Writer -> char oriented (internationalization)

• support for object serialization

• provide bridges between Java1.0 and Java1.1 classes• class for random access files

Class hierarchy structure

InputStream ReaderInputStreamReader

ObjectInputStream

Java1.1 classes

14

Java1.1 : Reader

Adaptation

InputStream

StringBufferInputStream

FileInputStream

PipedInputStream

SequenceInputStream

ByteArrayInputStream

FilterInputStream

Decorators

DataInputStream

BufferedInputStream

LineNumberInputStream

PushbackInputStream

Adaptation

Reader

StringReader

FileReader

PipedReader

CharArrayReaderFilterReader

Decorators

BufferedReader

LineNumberReader

PushbackReader

InputStreamReaderObjectInputStream

byte oriented char oriented

InflaterInputStream

15

Java1.1 : Writer

Adaptation

OutputStream

Decorators

ByteArrayOutputStream

FileOutputStream

PipedOutputStreamDataOutputStream

BufferedOutputStream

PrintStream

Adaptation

Writer

OutputStreamWriter

Decorators

CharArrayWriter

FileWriterPipedWriter

BufferedWriter

PrintWriter

StringWriter

FilterWriter

ObjectOutputStream

byte oriented char oriented

FilterOutputStream

DeflaterOutputStream

16

The Java IO system

OutputStream Writer

InputStream Reader

RandomAccessFile

adapt adapt

adapt adapt

decorate decorate

decorate decorate

bridge

bridge

• use char oriented classes when possible• use byte oriented classes when necessary

17

Compression

OutputStream

FilterOutputStream

DeflaterOutputStream

ZipOutputStream

GZIPOutputStream

CheckedOutputStream

InputStream

FilterInputStream

InflaterInputStream

ZipInputStream

GZIPInputStream

CheckedInputStream

18

Read text lines from file

class TextFileInput {

public static void main(String[] args) {

try {

System.out.println(readTextFile("lines.txt"));

} catch(IOException e) {

System.err.println("IO Error !");

}

}

public static String readTextFile(String n) throws IOException {

BufferedReader in=new BufferedReader(new FileReader(n));

String s,res="";

while((s=in.readLine())!=null) res+=s+"\n";

in.close();

return res;

}

} Use standard conversion methods to read primitives from text file :

Integer.parseInt(s);

Double.parseDouble(s);

19

Read text lines from terminalimport java.io.*;

class TextTerminalInput {

public static void main(String[] args) {

try {

System.out.println(readTextTerminal());

} catch(IOException e) {

System.err.println("IO Error !");

}

}

public static String readTextTerminal() throws IOException {

BufferedReader in=new BufferedReader(new InputStreamReader(System.in));

String s,res="";

System.out.print("Input text line : ");

while(!(s=in.readLine()).equals("")) {

res+=s+"\n";

System.out.print("Input text line : ");

}

return res;

}

}

InputStream

20

Write text to fileclass TextFileOutput {

public static void main(String[] args) {

String[] t={"First line","Second line","Third line"};

try {

writeTextFile("line.txt",t);

} catch(IOException e) {

System.err.println("IO Error !");

}

}

public static void writeTextFile(String n,String[] s) throws IOException {

PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(n)));

for(int i=0;i<s.length;i++)

out.println(s[i]);

out.flush(); // flush buffer

out.close(); // close file

}

}

21

Standard device redirectionclass RedirectOutput{

public static void main(String[] args) {

try {

System.setOut(new PrintStream(

new BufferedOutputStream(new FileOutputStream(args[1]))));

System.out.println(readTextFile(args[0]));

System.out.close();

} catch(IOException e) {

System.err.println("IO Error ! "+e);

}

}

// same as for reading text from file

public static String readTextFile(String n) throws IOException {

BufferedReader in=new BufferedReader(new FileReader(n));

String s,res="";

while((s=in.readLine())!=null) res+=s+"\n";

in.close();

return res;

}

}

System.setIn(InputStream)System.setOut(PrintStream)System.setErr(PrintStream)

22

Read text from memoryclass MemoryInput {

public static void main(String[] args) {

String mem="Read from memory !";

try {

StringReader s=new StringReader(mem);

int c;

while((c=s.read())!=-1) System.out.print((char)c);

} catch(IOException e) {

System.err.println("Error in StringReader.");

}

byte[] b=mem.getBytes();

DataInputStream in=new DataInputStream(new ByteArrayInputStream(b));

System.out.println("");

try {

while(in.available()!=0) System.out.print((char)in.readByte());

} catch(IOException e) {

System.err.println("Error in ByteArrayInputStream.");

}

}

}

Memory buffer : byte[ ]

Remaining number of bytes

23

Write binary to file

class BinaryFileOutput {

public static void main(String[] args) {

try {

DataOutputStream out=new DataOutputStream(

new BufferedOutputStream(new FileOutputStream("data.txt")));

out.writeFloat(3.14f);

out.writeDouble(3.1415926);

out.writeChar('t');

out.writeChars("Some text");

out.close();

} catch(IOException e) {

System.err.println("IO Error !");

}

}

}

24

Read binary from file

class BinaryFileInput {

public static void main(String[] args) {

try {

DataInputStream in=new DataInputStream(

new BufferedInputStream(new FileInputStream("data.txt")));

System.out.println(in.readFloat());

System.out.println(in.readDouble());

System.out.println(in.readLine()); // deprecated API !

in.close();

} catch(IOException e) {

System.err.println("IO Error !");

}

}

}3.143.1415926 t S o m e t e x t

25

Random access files

• unrelated to InputStream, OutputStream, Reader, Writer• constructor :

-file name-file mode : r [read only]

rw [read and write]• file pointer = index relative to file start (measured in bytes)

can be retrieved by : long getFilePointer()moved by : void seek(long)

• standard methods to read/writereadXXX : read primitive typewriteXXX : write primitive typereadUTF / write UTF : read/write StringreadLine : read String (line)read[Fully] / write[Fully] : read/write byte array

26

Random access files

class RandomAccess {

public static void main(String[] args) throws IOException {

RandomAccessFile r=new RandomAccessFile("random.dat","rw");

for(int i=0;i<10;i++) r.writeDouble(i*1.111);

for(int i=0;i<10;i+=2) {

r.seek(i*8); // 8 bytes for 1 double

r.writeDouble(i*1.1111);

}

// r.seek(10);

// r.writeInt(8);

r.seek(0);

while(r.getFilePointer()<r.length()) {

System.out.println(r.readDouble());

}

r.close();

}

}

0.0

1.0625000001265434

2.2222

3.333

4.4444

5.555

6.6666

7.777

8.8888

9.999

without //

0.0

1.111

2.2222

3.333

4.4444

5.555

6.6666

7.777

8.8888

9.999

with //

27

Serialization

= transform object into “wire format” (= bit sequence)

• store entire object on file (portable binary format)=> object can live beyond program termination

“lightweight persistence”used for JavaBeans (Java component model)

• send object across network=> application spread over multiple nodesdistributed computingused for Remote Method Invocation

(Java implementation of distributed objects)

28

Standard serialization

• class implements Serializable interface• writing :

create ObjectOutputStream (out)call out.writeObject(<object>)

• reading :create ObjectInputStream (in)call in.readObject()cast to specific class (result is of type Object)BUT : class file must be reachable by virtual machine !

29

Standard serialization

class A implements Serializable {private int a=0;private double b=12.0;private String s="Some data";public A() {System.out.println(" A() called.");}public A(int ia,double ib,String is) {

a=ia;b=ib;s=is;}public void setA(int ia) {a=ia;}public void setB(double ib) {b=ib;}public void setS(String is) {s=is;}public String toString() {

return "-> a="+a+" b="+b+" s="+s;}

}

30

Standard serializationclass WriteObject {

public static void main(String[] args) {

ArrayList o;

try { writeObjects("obj.dat");

} catch(IOException e) {System.err.println("Output Error : "+e);

}

try { o=readObjects("obj.dat");

for(int i=0;i<o.size();i++) System.out.println(o.get(i)); // no casting needed for toString

} catch(IOException e) { System.err.println("Input Error : "+e);

} catch(ClassNotFoundException e) { System.err.println("Class Error : "+e);

}

}

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1,10.0,"First.");A o2=new A(2,20.0,"Second.");

out.writeObject(o1);out.writeObject(o2);out.close();

}

public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {

ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));

ArrayList l=new ArrayList();

try { while(true) l.add(in.readObject());

} catch(EOFException e) {System.err.println("End of file reached.");}

in.close();

return l;

}

}

End of file reached.-> a=1 b=10.0 s=First.-> a=2 b=20.0 s=Second.

NO CONSTRUCTGOR CALLS TO RESTORE OBJECT !

31

Standard serializationStaticsclass A implements Serializable {

// .. Only changes shown …

private static char c;

public static void setC(char ic) {c=ic;}

public String toString() {

return "-> a="+a+" b="+b+" s="+s+" c = "+c;

}

public static void serializeStaticState(ObjectOutputStream o) throws IOException {

System.out.println("serializeStaticState().");

o.writeChar(c);

}

public static void deserializeStaticState(ObjectInputStream i) throws IOException {

System.out.println("deserializaStaticState().");

c=i.readChar();

}

}

Statics not serialized !IF needed :

• add custom static methods to serialize/deserialize static state• provide explicit calls for serializing/deserializing static state

32

Standard serializationStatics

class WriteObject { // … only changes shown …

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1,10.0,"First.");A o2=new A(2,20.0,"Second.");

A.setC('a');

out.writeObject(o1);

out.writeObject(o2);

A.serializeStaticState(out);

A.setC('b');

out.close();

}

public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {

ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));

ArrayList l=new ArrayList();

l.add(in.readObject());

l.add(in.readObject());

A.deserializeStaticState(in);

in.close();

return l;

}

}

serializeStaticState().deserializaStaticState().-> a=1 b=0.0 s=First. c = a-> a=2 b=0.0 s=Second. c = a

33

Aggregating serializablesclass A implements Serializable {

private int a=0;

private double b=12.0;

private String s="Some data";

private B myB;

public A() {System.out.println(" A() called.");}

public A(int ia,double ib,String is,B aB) {

a=ia;b=ib;s=is;myB=aB;

}

public void setA(int ia) {a=ia;}

public void setB(double ib) {b=ib;}

public void setS(String is) {s=is;}

public String toString() {

return "-> a="+a+" b="+b+" s="+s+myB;

}

}

class B implements Serializable { // MUST BE SERIALIZABLE !

private int c=0;

public B() {System.out.println(" B() called.");}

public B(int i) {c=i;};

public void setC(int ic) {c=ic;};

public String toString() {

return "\t c="+c;

}

}

34

Aggregating serializables

// … rest the same …

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1,10.0,"First.",new B(100));

A o2=new A(2,20.0,"Second.",new B(200));

out.writeObject(o1);

out.writeObject(o2);

out.close();

}

// …

End of file reached.-> a=1 b=10.0 s=First. c=100-> a=2 b=20.0 s=Second. c=200

Serialization mechanism follows the “web of objects”

35

Transient fieldsDo not serialize some fields :• some objects can not be serialized (e.g. Thread objects)• not logical to store permanently (e.g. password field) Mark fields as “transient”

class A implements Serializable {

private int a=0;

private transient double b=12.0;

private String s="Some data";

private transient B myB; // B not necessarily Serializable !

public A() {System.out.println(" A() called.");}

public A(int ia,double ib,String is,B aB) {

a=ia;b=ib;s=is;myB=aB;

}

public void setA(int ia) {a=ia;}

public void setB(double ib) {b=ib;}

public void setS(String is) {s=is;}

public String toString() {

return "-> a="+a+" b="+b+" s="+s+myB;

}

}

End of file reached.

-> a=1 b=0.0 s=First.null

-> a=2 b=0.0 s=Second.null

36

Customized serialization

Empty interface

Custom serialization

37

Customized serializationclass A implements Externalizable {

private int a=0;

private double b=12.0;

private String s="Some data";

public A() {System.out.println(" A() called.");}

public A(int ia,double ib,String is) {a=ia;b=ib;s=is;}

public void setA(int ia) {a=ia;}

public void setB(double ib) {b=ib;}

public void setS(String is) {s=is;}

public String toString() {return "-> a="+a+" b="+b+" s="+s;}

public void writeExternal(ObjectOutput o) throws IOException{

System.out.println("writeExternal().");

// super.writeExternal(o);

o.writeInt(a);o.writeDouble(b);o.writeObject(s);

}

public void readExternal(ObjectInput i) throws IOException,ClassNotFoundException {

System.out.println("readExternal().");

// super.readExternal(i);

a=i.readInt();b=i.readDouble();s=(String)i.readObject();

}

}

writeExternal().writeExternal(). A() called.readExternal(). A() called.readExternal().End of file reached.-> a=1 b=10.0 s=First.-> a=2 b=20.0 s=Second.

default constructor called ! (must be reachable !)

38

“TRICKY” Customized serialization

Customized serialization WITHOUT implementing Externalizable• implement Serializable• ADD (NOT override !) following methods :

• private void writeObject(ObjectOutputStream o) throws IOException• private void readObject(ObjectInputStream i) throws IOException

• customization options :• full customization• variation on standard serialization : use default methods

• o.defaultWriteObject()• i.defaultReadObject()

• this type of design can NOT be achieved in standard JAVA !

39

“TRICKY” Customized serialization

class A implements Serializable {

private int a=0;

private transient double b=12.0;

private String s="Some data";

public A() {System.out.println(" A() called.");}

public A(int ia,double ib,String is) {

a=ia;b=ib;s=is;

}

public void setA(int ia) {a=ia;}

public void setB(double ib) {b=ib;}

public void setS(String is) {s=is;}

public String toString() {

return "-> a="+a+" b="+b+" s="+s;

}

private void writeObject(ObjectOutputStream o) throws IOException{

System.out.println("writeObject().");

o.defaultWriteObject();

o.writeDouble((b<15.0) ? 0.0 : 100.0);

}

private void readObject(ObjectInputStream i) throws IOException,ClassNotFoundException {

System.out.println("readObject().");

i.defaultReadObject();

b=i.readDouble();

}

}

writeObject().writeObject().readObject().readObject().End of file reached.-> a=1 b=0.0 s=First.-> a=2 b=100.0 s=Second.

40

Inheritanceclass A implements Serializable {

private int a=0;

public A() {System.out.println(" A() called.");}

public A(int ia) {a=ia;}

public void setA(int ia) {a=ia;}

public String toString() {return super.toString()+"-> a="+a;}

}

class B extends A {

private int b=0;

public B() {System.out.println(" B() called.");}

public B(int ia,int ib) {super(ia);b=ib;};

public void setB(int ib) {b=ib;};

public String toString() {return super.toString()+"\t b="+b;}

}

class Serial1 {

// methods main and readObjects same as before

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1);

B o2=new B(2,20);

System.out.println(o1);System.out.println(o2);

out.writeObject(o1);out.writeObject(o2);

out.close();

}

}

A@6b97fd-> a=1B@1c78e57-> a=2 b=20End of file reached.A@8814e9-> a=1B@1503a3-> a=2 b=20

• no constructor calls• objects retrieved, stored at different location

41

Inheritanceclass A {

// same as before

}

class B extends A implements Serializable {

// same as before

}

class Serial2 { // main and readObjects same as before

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

B o2=new B(2,20);

System.out.println(o2);

out.writeObject(o2);

out.close();

}

}

B@6b97fd-> a=2 b=20 A() called.End of file reached.B@a83b8a-> a=0 b=20

• No-arg constructor called for unserializable base object• Only serializable part stored to and retrieved from stream

42

Inheritanceclass A implements Externalizable {

// same as before +

public void writeExternal(ObjectOutput o) throws IOException {

System.out.println("A.writeExternal().");

o.writeInt(a);

}

public void readExternal(ObjectInput i) throws IOException {

System.out.println("A.writeExternal().");

a=i.readInt();

}

}

class B extends A {

// same as before +

public void writeExternal(ObjectOutput o) throws IOException {

System.out.println("B.writeExternal().");

super.writeExternal(o);

o.writeInt(b);

}

public void readExternal(ObjectInput i) throws IOException {

System.out.println("B.writeExternal().");

super.readExternal(i);

b=i.readInt();

}

}

43

Inheritanceclass Serial3 {

// main and readObjects same as before

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1);

B o2=new B(2,20);

System.out.println(o1);System.out.println(o2);

out.writeObject(o1);out.writeObject(o2);out.close();

}

}

A@1c78e57-> a=1B@5224ee-> a=2 b=20A.writeExternal().B.writeExternal().A.writeExternal(). A() called.A.writeExternal(). A() called. B() called.B.writeExternal().A.writeExternal().End of file reached.A@c21495-> a=1B@1d5550d-> a=2 b=20

• call super-methods to store/retrieve base object (especially if private members …) • retrieving Externalizables ALWAYS calls constructor !

44

Aggregationclass A implements Serializable {

// clone method added to A

public Object clone() {return new A(a);}

}

class Serial4 {

// main and readObjects unchanged

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

A o1=new A(1);

System.out.println(o1);

out.writeObject(o1);

// out.close();

// out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

o1.setA(10);

System.out.println(o1);

out.writeObject(o1);

A o2=(A)o1.clone();

System.out.println(o2);

out.writeObject(o2);

out.close();

}

}

A@192d342-> a=1

A@192d342-> a=10

A@87816d-> a=10

End of file reached.

A@a83b8a-> a=1

A@a83b8a-> a=1

A@dd20f6-> a=10

with //

A@192d342-> a=1

A@192d342-> a=10

A@87816d-> a=10

End of file reached.

A@a83b8a-> a=10

A@dd20f6-> a=10

without //

• Serialization (to same stream !) avoids unnecessary (and dangerous) duplicates• Updates are unsafe !

45

Aggregationclass A implements Serializable {

private int a=0;

private B b;

public A() {System.out.println(" A() called.");}

public A(int ia,B ib) {a=ia;b=ib;}

public void setA(int ia) {a=ia;}

public B getB() {return b;}

public String toString() {

return super.toString()+"-> a="+a+b;

}

public Object clone() {return new A(a,(B)b.clone());}

}

class B implements Serializable {

private int b=0;

public B() {System.out.println(" B() called.");}

public B(int ib) {b=ib;};

public void setB(int ib) {b=ib;};

public String toString() {

return "\t"+super.toString()+" b="+b;

}

public Object clone() {return new B(b);}

}

46

Aggregationclass Serial5 { // main and readObjects unchanged

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

B b1=new B(10);

B b2=new B(20);

A a1=new A(1,b1);

//A a2=new A(2,b2); //[1]

//A a2=new A(2,(B)b1.clone()); //[2]

A a2=new A(2,b1); //[3]

System.out.println(a1);

System.out.println(a2);

out.writeObject(a1);

out.writeObject(a2);

out.close();

}

}

A@6b97fd-> a=1 B@1c78e57 b=10

A@5224ee-> a=2 B@f6a746 b=20

End of file reached.

A@743399-> a=1 B@e7b241 b=10

A@167d940-> a=2 B@e83912 b=20wit

h [

1]

A@6b97fd-> a=1 B@1c78e57 b=10

A@5224ee-> a=2 B@f6a746 b=10

End of file reached.

A@743399-> a=1 B@e7b241 b=10

A@167d940-> a=2 B@e83912 b=10

Serialization maintains “web of object logic”

A@6b97fd-> a=1 B@1c78e57 b=10

A@5224ee-> a=2 B@1c78e57 b=10

End of file reached.

A@1a1c887-> a=1 B@743399 b=10

A@e7b241-> a=2 B@743399 b=10

wit

h [

2]

wit

h [

3]

47

Aggregation// main and readObjects unchanged

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

B b=new B(10);

A a1=new A(1,b);

A a2=new A(2,b);

System.out.println(a1);

out.writeObject(a1);

b.setB(100);

System.out.println(a2);

out.writeObject(a2);

out.close();

}

A@6b97fd-> a=1 B@1c78e57 b=10

A@dd20f6-> a=2 B@1c78e57 b=100

End of file reached.

A@1a1c887-> a=1 B@743399 b=10

A@e7b241-> a=2 B@743399 b=10

48

Aggregation// main unchanged

public static void writeObjects(String n) throws IOException {

ObjectOutputStream out=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(n)));

B b=new B(10);

A a1=new A(1,b);

A a2=new A(2,b);

System.out.println(a1);

out.writeObject(a1);

System.out.println(a2);

out.writeObject(a2);

out.close();

}

public static ArrayList readObjects(String n) throws IOException,ClassNotFoundException {

ObjectInputStream in=new ObjectInputStream(new BufferedInputStream(new FileInputStream(n)));

ArrayList l=new ArrayList();

A a1=(A)in.readObject();

a1.getB().setB(100);

A a2=(A)in.readObject();

l.add(a1);

l.add(a2);

in.close();

return l;

}

A@192d342-> a=1 B@6b97fd b=10

A@a83b8a-> a=2 B@6b97fd b=10

A@1503a3-> a=1 B@1a1c887 b=100

A@743399-> a=2 B@1a1c887 b=100

49

Conclusion

3 options to serialize• implement Serializable (some customization possible using “transient”)• implement Externalizable (full customization necessary)• use trick with Serializable

Serialization is not identical to writing to standard stream• web of objects is maintained• changes to objects while stream is open : considered unsafe

Advice : consider serialization “Atomic”• collect all related objects in 1 collection• store/retrieve in 1 serialization operation