Java 加载序列化对象

Java 加载序列化对象,java,serialization,Java,Serialization,我开始学习java,并开始学习序列化。我想知道是否有办法在类本身内部编写反序列化函数。让我澄清一下我的意思:我可以从另一个类中反序列化一个对象(即从classPerson),它可以工作: public class Dummy{ ... public static void main(String args[]) { ... Person father = null; try { FileInputSt

我开始学习java,并开始学习序列化。我想知道是否有办法在类本身内部编写反序列化函数。让我澄清一下我的意思:我可以从另一个类中反序列化一个对象(即从class
Person
),它可以工作:

public class Dummy{
    ...
    public static void main(String args[])
    {
        ...
        Person father = null;
        try {
            FileInputStream load = new FileInputStream(saved_file);
            ObjectInputStream in = new ObjectInputStream(load);
            indiv = (Person) in.readObject();
            in.close();
            load.close();
        } catch (...) { ... }
     }
 }
但是,为了保持整洁,是否可以将其作为函数移动到Person类中?例如,要执行以下操作:

public class Person implements Serializable {

    private boolean isOrphan = false;
    private Person parent;
    ...

    public void load(File saved_file) {
        try {
            FileInputStream load = new FileInputStream(saved_file);
            ObjectInputStream in = new ObjectInputStream(load);
            this = (Person) in.readObject(); // Error: cannot assign a value to final variabl this
            in.close();
            load.close();
         } catch (...) { ... }
     }
}
然后在另一个类中,我们称之为:

public class Dummy{
    ...
    public static void main(String args[])
    {
        ...
        Person father = null;
        father.load(saved_file);
    }
}

不能对尚不存在的实例调用实例方法。即使你的代码可以编译,你也会得到一个
NullPointerException
,因为你在
null
上调用一个方法

将方法设为静态,并使其返回反序列化实例。更一般地说,
不是可以指定的变量,它是对对象的不可变引用

public static Person load(File saved_file) {
    try (FileInputStream load = new FileInputStream(saved_file);
         ObjectInputStream in = new ObjectInputStream(load)) {
        return (Person) in.readObject();
     } catch (...) { ... }
 }

public class Dummy {
    public static void main(String args[]) {
        Person father = Person.load(saved_file);
    }
}

PS:我还添加了try-catch with-resources,而不是显式的
close()
,因为这样更安全。

您不能对尚不存在的实例调用实例方法。即使你的代码可以编译,你也会得到一个
NullPointerException
,因为你在
null
上调用一个方法

将方法设为静态,并使其返回反序列化实例。更一般地说,
不是可以指定的变量,它是对对象的不可变引用

public static Person load(File saved_file) {
    try (FileInputStream load = new FileInputStream(saved_file);
         ObjectInputStream in = new ObjectInputStream(load)) {
        return (Person) in.readObject();
     } catch (...) { ... }
 }

public class Dummy {
    public static void main(String args[]) {
        Person father = Person.load(saved_file);
    }
}

PS:我还添加了try catch with resources,而不是explicit
close()
,因为这样更安全。

谢谢!序列化时是否也建议使用“try catch with resources”(尝试捕获资源)?无论何时使用IO或其他
Closeable/AutoCloseable
,都建议使用它。它所做的是确保
try(this_part){而不是this_one}中声明的所有资源无论发生什么情况,
都将始终关闭。例如,在您的代码中,如果在关闭文件之前在
try
块中引发异常,则您将永远不会关闭它。您可以通过将关闭操作移动到
finally
块来修复代码,但这会更加冗长,并且您可能会在尝试ca时忘记执行此操作如果您正确使用tch with resources,它可以为您做任何事情。谢谢!在序列化时,是否也建议您使用“try catch with resources”(尝试捕获资源)?建议您在使用IO或其他
可关闭/自动关闭的
时使用它。它所做的是确保无论发生什么情况,
try(this_part){not_this_one}
中声明的所有资源都将始终关闭。例如,在您的代码中,如果在关闭文件之前在
try
块中抛出异常,那么您将永远不会关闭它。您可以通过将close操作移动到
finally
块来修复代码,但它更为冗长,而且您可能会忘记这样做,而try-catch-with-resources可以为您解决所有问题,只要您使用正确。