为什么我的 "marshaller" 必须是 "static"?
Why does my "marshaller" have to be "static"?
我正在尝试 "marshall" 和 "unmarshall" 对象,在它们自己的 class 中,并使用 "Marshaller".
主要方法:
public class Main {
public static void main(String[] args) {
new Something();
}
}
"Something" class 将生成要编组或解组的实例:
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);
}
}
这是编组器:
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();
}
}
}
在 class Something
中,如果我的 Marshaller 没有声明 "static",我会得到一个 java.io.NotSerializableException
。为什么?
感谢您的回答,帮助我理解。
祝你有美好的一天。
PS : 我应该使用 marshall
还是 serialize
这个词?
当您序列化一个对象时,从该对象可到达的所有对象也会被存储,因此它们都必须是 serializable
。如果你声明你的 class 像:
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();
}
那么来自 class Something
的任何实例的可访问字段是 value
、file
和 marshaller
,因此 jvm 也会尝试将它们序列化,这就要求它们每个都必须是serializable
,但是class Marshaller
不是,那么就会出现异常。
当您将字段声明为 static
时,您使它成为 class 的成员,而不是单个实例,因为序列化只关心实例的当前状态,只关心与特定实例将被序列化,因此所有静态字段都将被忽略,您的程序可以正常运行。
如果确实需要一个字段作为实例成员,但又不想序列化,需要用关键字transient
声明,那么在序列化过程中会被忽略。
而对于 marshall
和 serialize
这个词,我不是以英语为母语的人,所以我不能说太多它们之间的区别,但我个人更喜欢 [=21] =] 在这种情况下,并在处理 JSON/XML from/to java 对象时使用 marshall
。
希望这对您有所帮助:-)
我正在尝试 "marshall" 和 "unmarshall" 对象,在它们自己的 class 中,并使用 "Marshaller".
主要方法:
public class Main {
public static void main(String[] args) {
new Something();
}
}
"Something" class 将生成要编组或解组的实例:
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);
}
}
这是编组器:
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();
}
}
}
在 class Something
中,如果我的 Marshaller 没有声明 "static",我会得到一个 java.io.NotSerializableException
。为什么?
感谢您的回答,帮助我理解。
祝你有美好的一天。
PS : 我应该使用 marshall
还是 serialize
这个词?
当您序列化一个对象时,从该对象可到达的所有对象也会被存储,因此它们都必须是 serializable
。如果你声明你的 class 像:
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();
}
那么来自 class Something
的任何实例的可访问字段是 value
、file
和 marshaller
,因此 jvm 也会尝试将它们序列化,这就要求它们每个都必须是serializable
,但是class Marshaller
不是,那么就会出现异常。
当您将字段声明为 static
时,您使它成为 class 的成员,而不是单个实例,因为序列化只关心实例的当前状态,只关心与特定实例将被序列化,因此所有静态字段都将被忽略,您的程序可以正常运行。
如果确实需要一个字段作为实例成员,但又不想序列化,需要用关键字transient
声明,那么在序列化过程中会被忽略。
而对于 marshall
和 serialize
这个词,我不是以英语为母语的人,所以我不能说太多它们之间的区别,但我个人更喜欢 [=21] =] 在这种情况下,并在处理 JSON/XML from/to java 对象时使用 marshall
。
希望这对您有所帮助:-)