140 likes | 287 Views
Serialization, Cont’d. Cerealization?. Administrivia. Reminders: Swing/events quiz (group/indiv): next Mon, Feb 14 Book text, BUT ALSO try some demo programs yourself Reading 1: due Mon Feb 21 Update to P1 M3: write query results to a file Example format will be in P1 spec v. 1.2
E N D
Serialization, Cont’d Cerealization?
Administrivia • Reminders: • Swing/events quiz (group/indiv): next Mon, Feb 14 • Book text, BUT ALSO try some demo programs yourself • Reading 1: due Mon Feb 21 • Update to P1 M3: write query results to a file • Example format will be in P1 spec v. 1.2 • Adherence to format spec is critical!
Gotchas #0.5 • Suppose: • class Foo extends Bar implements Serializable • but... • Bar does not implements Serializable • What happens when you (de-)serialize Foo?
Serialization order of ops • ObjectInputStream.readObject(myObj) • Loads class name →CName • Loads class by searching for CName on $CLASSPATH→CObj • Checks CName’s class version (*) • Calls CObj’s no-arg constructor to create a “blank” object of type CName→tmp • Calls tmp.readObject(stream) to load tmp • Usually same as stream.defaultReadObject • May recurse into loading sub-objects • Returns tmp
Superclasses, cont’d • Foo and Bar must exist on class path • Or step 2 fails • Bar must provide a no-arg constructor • Or step 4 fails • Override Foo.readObject()/writeObject() to save/load Bar’s protected/private state • Foo must have access or Bar must provide protected accessor methods
Superclasses, cont’d • Order of operations (deserializing Foo): • Java calls Foo’s no-arg constructor • Java calls Bar’s no-arg constructor • Java calls Foo.readObject() • Foo.readObject() reads Bar’s saved state; initializes the Bar part of Foo • Foo.readObject() reads its own saved state and updates its own saved data • Foo.readObject() calls readObject() for each of its child objects
Gotchas #1 • Efficiency • You can just mark MondoHashMap as Serialziable and let Java do all the hard work • But, that’s not as efficient as you could be, and might be wrong • By default, Java will store entire internal _table, including null values ⇒ lot of storage overhead • Wasting time to load/store all those null entries • hashCode()s of keys may not be same after deserialization ⇒ should re-hash to be sure
Gotcha #2 • Backward compatibility • Suppose: You write class Foo v. 1.0 • Serialize an instance of Foo to file “foo-1.0.dat” • Later, add new private members to Foo⇒ Foo 1.1 • Keep public methods/data all the same • Foo 1.1 should have same semantics and be interchangeable w/ Foo 1.0 • What happens when you deserialize Foo 1.1 from foo-1.0.dat?
Serial versioning • Issue is: in code, only changes to public or protected members make any difference • (So long as semantics of methods unchanged) • With Serialization, all of a sudden, private members now also are part of the “object signature” • (Why doesn’t this happen in single program run?) • Have to be very careful not to muck up internals in a way that’s inconsistent w/ previous versions of class • E.g., changing meaning, but not name of a member
Serial versioning, cont’d • Example: • // version 1.0 • public class MyClass implements Serializable { • public MyClass(int i) { • _data=2*i; • } • private int _data; • } • // version 1.1 • public class MyClass implements Serializable { • public MyClass(int i) { • _data=3*i; // SEVERE NO-NO! • } • private int _data; }
Serial versioning, cont’d • Java helps as much as it can • Tracks a “version number” for each class that changes when the class changes “substantially” • Fields changed to/from static or transient • Field or method names changed • Data types changed • Class moves up/down in class hierarchy • Does not track code, local vars, comments, etc. • Trying to deserialize a class of a version different than that on the $CLASSPATH⇒ InvalidClassException
Serial versioning, cont’d • Java version number comes from names and signatures of all data and method members of a class • Names/sigs don’t change ⇒ Java won’t notice a change • ⇒ If you want Java to detect a change, change a name • But if you’ve only changed names or refactored private functionality, you want to be able to tell Java that nothing has changed about your class • Can lie to Java about version number: • static final long serialVersionUID=-7951488742677775723L; • (Use serialver cmd to get version # for a class)
Design exercise: re-iterate • Given • An Iterator object (returned by some method) • A function, f: public Object f(Object) • Design: • class ReIterator implements Iterator • Such that: • ReIterator.next() returns f applied to Iterator.next() • f() is interchangeable (call to f not hardcoded in to ReIterator) • ReIterator requires only O(1) space • Iterator.next() not called more often than ReIterator.next()