在构造函数中从已保存的对象创建对象

时间:2017-04-14 15:35:47

标签: java

要清楚:我有一个在运行时期间不断更改其值的对象,我想将创建和修改的对象保存在文件中。 我发现了如何做到这一点,我还发现了如何回读对象,将其保存到另一个对象中。但问题是:是否可以使用我想要检索的对象存储的文件的唯一参数来调用我的对象的类构造函数?

NeuralNetwork(File fs){
    ObjectInputStream ois;
    changeFileSave(fs);      //just sets the file as savefile for the future
    try{
        ois = new ObjectInputStream(new FileInputStream(_saveNet));  //_saveNet = fs
        this = (NeuralNetwork) ois.readObject();
    }
    catch(Exception e){
        //error message
    }
}

它给我一个错误' this =' 如果可能,我该怎么办?

谢谢

3 个答案:

答案 0 :(得分:1)

关键字this是只读引用,即使在构造函数中也不能写this =。而且,java中的构造函数不返回任何内容。

您必须将您已阅读的对象逐个(或使用反射)逐个(或使用反射)映射到您正在实例化的对象中的属性。

但是,我会通过将文件传递给构造函数并在其中执行IO来提交,这违反了关注点的分离。通过这种方式编写东西,你已经永远将神经网络绑定到一个文件,其中包含许多附带的问题,包括(不限于)你可能在某些时候将值存储在其他地方的事实。

IMO您最好使用factory pattern构建对象并使您的NeuralNetwork对象成为普通对象。然后歧义消失,因为您的工厂方法可以简单地返回(NeuralNetwork) ois.readObject();

答案 1 :(得分:1)

this = (NeuralNetwork) ois.readObject();

this视为隐藏final参数,该参数指向正在执行该方法的实例。它的价值无法改变。如果你想让一个变量指向一个实例,只要你不使用this就没有问题。

您想要做的更适合factoryfactory method而不是构造函数。使用这种模式之一(或静态方法,如果你想保持它非常简单)从文件创建实例。不确定您是否需要该类的多个实例,但如果您只需要一个,则应考虑使用Singleton getInstance()方法,而不是前面提到的方法。

答案 2 :(得分:0)

您无法分配this,因为它是只读的。 this始终指向实例本身,并在对象的整个生命周期中使用它来访问其方法和属性。

如果要通过读取文件中的数据来创建NeuralNetwork类的实例,可以使用工厂方法:

public class NeuralNetwork {

    private NeuralNetwork() { // private constructor forces us to use the
    }                         // factory method to create instances

    public static NeuralNetwork loadFromFile(File fs) {
        ObjectInputStream ois;
        this.changeFileSave(fs); // just sets the file as savefile for the future
        try {
            ois = new ObjectInputStream(new FileInputStream(_saveNet));
            return (NeuralNetwork) ois.readObject();
        }
        catch(IOException e){
            throw UncheckedIOException(e);
        }
    }

    // other methods and attributes
}

然后,无论您在何处使用NeuralNetwork类并需要实例,请使用:

NeuralNetwork network = NeuralNetwork.loadFromFile(someFs);
// use network instance and have fun with it here

注1:我已经定义了一个私有构造函数来强制每个人使用loadFromFile工厂方法来创建实例。这意味着只能在此类的静态方法中创建此类。

注意2:我还使用未经检查的异常重新抛出异常。这是个人品味。我不会只记录异常并继续。相反,我会抛出异常,以便调用者正确处理它,因为如果尚未创建类的实例,那么继续执行它是没有任何意义的。如果您不想将异常重新抛出为未经检查的异常,则不要捕获原始IOException并在工厂方法中添加throws IOException子句。这会强制loadFromFile的调用者捕获IOException并处理它。