我无法在Java中对一个对象进行序列化和反序列化。

3

在Java(8)中序列化对象时,我遇到了一个问题。我看了很多例子,但是它们都不适用于我。问题在于,在序列化时它没有将完整的数据与对象一起序列化。当我尝试反序列化时,它会将所有变量读取为null值。我是使用Employee类进行这个操作的。Serialize.java代码如下:

public class Serialize {
private static ArrayList<Employee> emp = new ArrayList<Employee>();
public static void main(String[] args){
    try{

            emp.add(new Employee("Areg Hovhannisyan",5));
            emp.add(new Employee("Tigran Hakobyan",15));
            emp.add(new Employee("Shivanshu Ojha",11));
            FileOutputStream fos = new FileOutputStream("emps.emp");
            ObjectOutputStream out = new ObjectOutputStream(fos);
            out.writeObject(emp);

            out.close();
            fos.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
}
}

Employee.java:

import java.io.Serializable;
public class Employee implements Serializable {
private static int age;
private static String name;

public static int getAge() {
    return age;
}
public static void setAge(int age) {
    Employee.age = age;
}
public static String getName() {
    return name;
}
public static void setName(String name) {
    Employee.name = name;
}


public Employee(String name,int i) {
    this.name = name;
    this.age = i;
}
@Override
public String toString() {
    return "Name : " + getName() + ", Age : " + getAge();
}

}

请给出一个例子来做到这一点,如何进行反序列化,请附上解释,因为我也想了解它的工作原理。

你忘记了员工类。 - Seelenvirtuose
你的错误是什么?你尝试了什么来达到某个结果?请先阅读此内容:如何提出一个好问题? - Nagy Vilmos
为什么在你的员工类中,年龄和姓名是静态字段? - Gerard Rozsavolgyi
@GerardRozsavolgyi 这正是 OP 的问题(也是我要求那个类的原因)。 - Seelenvirtuose
4个回答

2
这是因为你的类中的字段是静态的。静态字段隐式地被认为是瞬态的,我们无法序列化瞬态字段。

谢谢,但您能否建议我一种访问我想在Employee类中序列化的变量的方法?如果它们不是静态的,我无法从Employee类中访问它们。我尝试使用getter和setter,但它没有起作用。我尝试使用eclipse生成getter和setter,但当我尝试使用它们时,它们不是静态的。我应用了static修饰符,但出现了错误。也无法通过“this.”或“Employee.”访问变量。 - user4685210

0
如上所述,静态变量隐式地是短暂的。另外,根据您的代码,如果变量是静态的,则在您的ArrayList中将有一个值(最终添加的值)。这是静态变量的行为。
请给出一个示例来执行此操作,如何反序列化。
带有反序列化的代码:
public static void main(String[] args) throws IOException,
        ClassNotFoundException {
    FileOutputStream fos = null;
    ObjectOutputStream out = null;
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try {

        emp.add(new Employee("Areg Hovhannisyan", 5));
        emp.add(new Employee("Tigran Hakobyan", 15));
        emp.add(new Employee("Shivanshu Ojha", 11));
        fos = new FileOutputStream("emps.emp");
        out = new ObjectOutputStream(fos);
        out.writeObject(emp);

        fis = new FileInputStream("emps.emp");
        in = new ObjectInputStream(fis);
        ArrayList<Employee> empRead = (ArrayList) in.readObject();
        System.out.println(empRead.get(0));
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        out.close();
        fos.close();
    }
}

0
你代码中唯一的问题是 agename 字段不应该是静态的,如果你想要实现的话...
只需要移除这两个 static 修饰符,你的代码就可以正常工作了。
然后你可能需要了解一下 static 修饰符的相关知识,以理解为什么你的代码不能正常工作。

谢谢,但您能否建议我一种访问我想在Employee类中序列化的变量的方法?如果它们不是静态的,我无法从Employee类中访问它们。我尝试使用getter和setter,但它没有起作用。我尝试使用eclipse生成getter和setter,但当我尝试使用它们时,它们不是静态的。我应用了static修饰符,但出现了错误。也无法通过“this.”或“Employee.”访问变量。 - user4685210
一旦你有了你的数组列表,尝试迭代它并打印每个实例的toString...你会发现你的代码并没有做你期望它做的事情。问题在于你不应该为你想要的东西使用static,而getter和setter也不应该这样做。 - Vinze
好的,我的错误,明白了,我会使用修饰符protected。 - user4685210

0

类的默认可序列化字段被定义为非瞬态非静态字段。

Oracle链接

这里是相关的Stack Overflow链接。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接