Archive for December, 2007

Serialization

Lets first take a short look into how serialization works.Here is my simple example

public static void main(String[] args) {
 Cat myCat = new Cat("kitty", 10); System.out.println("before:" + myCat.getName() + " " + myCat.getAge());
ObjectOutputStream ous = null; try {  FileOutputStream fos = new FileOutputStream("Cat.ser");  ous = new ObjectOutputStream(fos);
ous.writeObject(myCat);  ous.flush();
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  if (ous != null) {
   try {
    ous.close();
   } catch (IOException e) {   }
  }
 }
 ObjectInputStream ois = null; try {  FileInputStream fis = new FileInputStream("Cat.ser");  ois = new ObjectInputStream(fis);
  myCat = (Cat) ois.readObject();
  System.out.println("after:" + myCat.getName() + " "    + myCat.getAge());
 } catch (Exception e) {
  e.printStackTrace();
 } finally {
  if (ois != null) {
   try {
    ois.close();
   } catch (IOException e) {   }
  }
 }
} 

The first significant thing has to be remembered is to make Cat class implement Serializable interface (no abstract methods, just a marker interface). Otherwise java.io.NotSerializableException is thrown.

 public class Cat implements Serializable{
 private int age; private String name;
 public Cat(String string, int i) {
 name = string; age = i;
 } //getters
 }

Here the state and the object graph of the myCat object is saved into the file and then it is read from the file and it could be seen that the values of the fields are the same as the values just before saving the object.

But is myCat refers to the same object in the heap?
Actually no, when look before serialization and after deserialization it can seen that the hashcodes values are changed and if the read object is assigned to another cat object and compared myCat object with that cat object the result is false.

Cat newCat = (Cat) ois.readObject(); Sytem.out.println(myCat.equals(newCat));

When reading a new object with the same object graph is created in the heap and its address is assigned to myCat object.
When you serialize an object, Java serialization takes care of saving that object’s entire “object graph.” That means a deep copy of everything the saved object needs to be restored.

Lets change Cat class and extend Cat from Animal which is a non-serializable class.

 public class Animal {
 String name;
 public Animal(String name) {
 System.out.println("constructor for Animal");
 this.name = name;
 }
public Animal() {
 System.out.println("Default constructor for Animal");
 }
 }

And Cat class becomes like this:

 public class Cat extends Animal implements Serializable {
 private int age;
 public Cat(String string, int i) {
 super(string); age = i;
 } //getters
 }

Cat class is serializable but the base class Animal is not. This means only age field could be written and read with the same values. When serialization occurs the no-arg constructor of the Animal class is called so the serialized cat object would have null value for name field.

What would happen if Animal class didn’t have a no-arg constructor? (Remove the code below from Animal class)

public Animal() {
 System.out.println("Default constructor for Animal");
 }

In this case since the Animal has a constructor with arguments, JVM doesn’t assign a no-arg constructor for this class,java.io. InvalidClassException would occur with the message “com.foo.serialization.Cat; no valid constructor”.

Leave a Comment

The StringBuffer and StringBuilder Classes

If there has to be done lots of string manipulations, using String class would be a waste of memory since String class is immutable there would be lots of abandoned string objects in the string pool when manipulations are being done.
StringBuffer and StringBuilder Classes would handle such manipulations with efficient use of memory because these classes are not immutable and can reuse the same memory over and over. A common use of these classes is IO operations.
StringBuilder was added in Java 5. It has the same methods as the StringBuffer has but its methods are not synchronized and so it is not thread safe. So it runs faster than StringBuffer.

Leave a Comment

Older Posts »