I'm trying to "marshall" and "unmarshall" objects, in their own class, and using a "Marshaller".
The Main method :
public class Main {
public static void main(String[] args) {
new Something();
}
}
The "Something" class that will produce the instances to marshall or unmarshall :
import java.io.File;
import java.io.Serializable;
public class Something implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
public int value = 2;
private File file = new File("something.serial");
private static Marshaller marshaller = new Marshaller();
Something() {
value = 3;
marshaller.marshalling(file, this);
Something anotherThing = (Something) marshaller.unmarshalling(file);
System.out.println(anotherThing.value);
}
}
Here is the Marshaller :
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Marshaller {
public Marshaller() {
}
/**
* Charge l'objet sérializé d'un fichier si il existe
* @param file : le fichier à désérialiser
* @return obj : l'instance d'objet désérialisé
*/
public Object unmarshalling(File file) {
Object obj = null;
ObjectInputStream ois;
try {
BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(file));
ois = new ObjectInputStream(bis);
obj = ois.readObject();
ois.close();
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
return obj;
}
/**
* Permet d'enregistrer un objet (settings, client...) dans un fichier
* @param file : le fichier support de la sérialisation
* @param obj : l'instance d'objet à sérialiser
*
*/
public void marshalling(File file, Object obj) {
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(
new BufferedOutputStream(
new FileOutputStream(file)));
oos.writeObject(obj);
oos.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
In the class Something
, if my Marshaller isn't declared "static", I get a java.io.NotSerializableException
. Why ?
Thank you for your answers to help me to understand.
Have a good day.
PS : Shall I use the word marshall
or serialize
?
When you serialize an object, all of the objects that are reachable from that object are stored as well, so all of them must be serializable
. If you declare your class like:
public class Something implements Serializable {
private static final long serialVersionUID = 1L;
public int value = 2;
private File file = new File("something.serial");
private Marshaller marshaller = new Marshaller();
}
Then reachable fields from any instance of class Something
are value
, file
and marshaller
, so jvm will try to serialize them as well, which requires each of them must be serializable
, but class Marshaller
is not, then exception happens.
When you declare a field as static
, you make it a member of the class, not individual instance, since serialization only cares about the current state of instances, only data associated with a specific instance will be serilized, therefore all static fields are ignored and your program works OK.
If you do need a field be instance member but don't want it to be serialized, you need to declare it with keyword transient
, then it'll be ignored during the serialization.
And for the word marshall
and serialize
, I'm not a native English speaker so I cann't tell too much about the difference between them, but personally I prefer serialize
in this case, and use marshall
when dealing JSON/XML from/to java objects.
Hope this could be helpful to you :-)