一旦方法返回,传递给方法的列表和反序列化变为空

时间:2014-01-13 19:25:28

标签: java generics serialization collections

我有一个方法:

static <E extends NotesAttached> void deserialise(List<E> list, String type) {
    String fileName = "C:/temp/SalesModel." + type + ".list.ser";
    try {
        FileInputStream serFile = new FileInputStream(fileName);
        ObjectInputStream in = new ObjectInputStream(serFile);
        list = (List<E>) in.readObject();
        in.close();
        serFile.close();
        System.out.println(type + "s deserialised successfully, " + list.size() + " retrieved");
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}

我称之为:

    List<Deal> deals = new ArrayList<Deal>();
    deserialise(deals, "Deal");
    System.out.println("Number of deals deserialised: " + deals.size());

列表在方法中填充,但是当它返回时,它是空的。我不明白为什么,如果有人可以解释,我会很感激。

输出如下:

成功反序列化,检索2522 反序列化的交易数量:0

3 个答案:

答案 0 :(得分:5)

您反序列化的列表不会“变空” - 但deals变量不会引用您刚刚反序列化的列表...它指的是它所执行的相同的空列表在调用方法之前。更改方法中list参数的值会对您传递的参数 nothing ,因为Java使用pass by value。

您最好不要使用void方法,而是返回列表:

static <E extends NotesAttached> List<E> deserialise(String type)
        throws IOException, ClassNotFoundException {
    String fileName = "C:/temp/SalesModel." + type + ".list.ser";
    FileInputStream serFile = new FileInputStream(fileName);
    ObjectInputStream in = new ObjectInputStream(serFile);
    try {
        List<E> list = (List<E>) in.readObject();
        System.out.println(type + "s deserialised successfully, " + list.size() + " retrieved");
        return list;
    } finally {
        // See notes
        in.close();
        serFile.close();
    }
}

并将其命名为:

List<Deal> deals = deserialise(deals, "Deal");
System.out.println("Number of deals deserialised: " + deals.size());

你需要处理ClassNotFoundExceptionIOException,但他们最好不要在方法之外处理 - 你几乎肯定想要抓住它们,转储堆栈跟踪并继续,好像什么都没有出错。

这不是完全正确,因为你真的想关闭流而不管其他错误。如果您可以使用Java 7,则可以使用try-with-resources语句:

static <E extends NotesAttached> List<E> deserialise(String type)
        throws IOException, ClassNotFoundException {
    String fileName = "C:/temp/SalesModel." + type + ".list.ser";
    try (FileInputStream serFile = new FileInputStream(fileName),
         ObjectInputStream in = new ObjectInputStream(serFile)) {
        List<E> list = (List<E>) in.readObject();
        System.out.println(type + "s deserialised successfully, " + list.size() + " retrieved");
        return list;
    }
}

如果您遇到Java 6,我可能会使用嵌套的try / finally块 - 或关闭FileInputStream,因为ObjectInputStream没有无论如何都要抓住任何非托管资源。

答案 1 :(得分:2)

当您将in.readObject()分配给list时,您不会更改在方法之外实例化的列表 - 您只是将list引用更改为指向in.readObject()的结果{1}}而不是您传入的列表。

您需要从方法中返回in.readObject(),然后将结果分配给新变量:

List<Deal> deals = deserialise(deals, "Deal");

或者你可以修改deserialise中的传入列表(但不建议这样做,因为修改传入的集合不是从方法返回数据的好方法):

list.addAll((List<E>) in.readObject());

答案 2 :(得分:1)

Java是按值传递,因此您必须返回反序列化列表,而不是将其分配给输入参数