扩展ArrayList并引用构造函数中的反序列化对象

时间:2013-03-04 23:37:11

标签: java this

我有一个名为Library的类,它扩展了ArrayList。我之所以这样做是因为(我认为)库类和ArrayList之间存在真正的关系 - 图书馆只是书籍的集合,还有一些方法。

其中一个方法是load(),它反序列化已保存的Library对象。我的问题是:如何将反序列化的对象变为库的“活动”实例?我想在库的构造函数中执行this = load()之类的操作,因为load()返回一个Library对象。但是,当我尝试执行此操作时,我收到编译器错误cannot assign a value to final variable this。用于此目的的正确语法是什么?

public class Library extends ArrayList<Book> implements Serializable{

public Library(){
    load();
}
...

Library load() throws IOException, ClassNotFoundException {
    File f = new File (System.getProperty("user.home")+"\\Documents\\CardCat\\library.ser");   
    ObjectInputStream ois = new ObjectInputStream (new FileInputStream (f));   
    Library lib = (Library)ois.readObject();
    System.out.println("ran load sucessfully");
    return lib;
}
编辑:似乎普遍的共识是这是错误的方法,我应该创建一个不扩展ArrayList但具有ArrayList实例变量的Library类。这实际上是我一小时前的结构,但我认为扩展ArrayList可能会更简单一些。我的主要理由是ArrayList是Library类的唯一变量,我经常从其他类中引用ArrayList,每次我这样做时都要调用library.libList,所以我认为能够简单地引用library会更简单。回顾过去,并考虑到您的意见,这似乎是一个相当微不足道的好处,它的代价是对性能的重大打击。

虽然我想更好地了解这些费用是什么,但我能正确理解你的想法吗?我(显然,我很确定)仍在学习和尝试各种各样的事情,并非常感谢任何帮助我识别失败实验的输入。

4 个答案:

答案 0 :(得分:2)

can't overwrite this by design

需要考虑的一些事项:

  • 为什么库是ArrayList?是否有任何需要将库分配给ArrayList的情况?库必须是否为List并由数组支持是否有任何理由?实现Collection可能是合理的,但会强制您实现在您的设计中可能没有意义的方法。
  • 如果库不是ArrayList,那么您可以使用composition,这样更容易使用。只需要一个成员变量,它是一个ArrayList(或任何类型的集合)。
  • 对于反序列化,通常使用静态函数或工厂,而不是构造函数。请参阅其他答案以了解如何执行此操作。

为了在下面用代码阐明我的评论,这里是一个将书籍添加为实例变量的示例,然后创建从外部访问它们所需的任何方法:

class Library {
    private final Collection<Book> books = new ArrayList<Book>();

    public void addBook(Book book) {
        this.books.add(book);
    }

    public Collection<Book> getAllBooks() {
        ...
    }

    public Book getBookByTitle(String title) {
        ...
    }
}

答案 1 :(得分:1)

你应该加载而不是制作Library的新实例。

答案 2 :(得分:1)

执行此操作的正确方法是使load方法返回一个全新的实例:

答案 3 :(得分:1)

你可以这样做:

public Library(){
    addAll(load());
}

正如其他人所说,这不是最好的设计实践,但也许你正在做一些我们不知道的事情。