为什么我无法从文件中读取 List 对象(Java IO)

huangapple go评论121阅读模式
英文:

Why I cannot read List object from my file (Java IO)

问题

以下是翻译好的内容:

我有一个像这样写入 `List<String>` 到文件的方法

```java
public static void main(String[] args) {
    List<String> data = Arrays.asList("1", "2", "3", "4", "5");
    writeObjectToFile(data, "demo.dat");
    
    List<String> result = null;
    readObjectFromFile(result, "demo.dat");
    System.out.println(result);
}

使用 writeObjectToFile 方法写入数据:

public static <T> void writeObjectToFile(List<T> obj, String fileName) {
    File file = new File(fileName);
    FileOutputStream fos = null;
    ObjectOutputStream oos = null;

    try {
        fos = new FileOutputStream(file);
        oos = new ObjectOutputStream(fos);
        oos.writeObject(obj);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 关闭 fos,oos 等...
    }
}

以及 readObjectFromFile 方法:

public static <T> void readObjectFromFile(List<T> obj, String fileName) {
    File file = new File(fileName);
    FileInputStream fis = null;
    ObjectInputStream ois = null;

    if (file.exists()) {
        try {
            fis = new FileInputStream(file);
            ois = new ObjectInputStream(fis);
            Object readObject = ois.readObject();
            obj = (List<T>) readObject;
            System.out.println(obj);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭 fis,ois 等...
        }
    }
}

写入文件的步骤是正确的,但读取步骤未按预期工作。我得到的 result 列表为 null

// 控制台输出
[1, 2, 3, 4, 5] // --> 这是 System.out.println(obj) 的结果;
null            // --> 这是 System.out.println(result) 的结果;

但是当我将读取方法更改为返回列表时:

public static <T> List<T> readObjectFromFile(String fileName) {
    File file = new File(fileName);
    FileInputStream fis = null;
    ObjectInputStream ois = null;

    if (file.exists()) {
        try {
            fis = new FileInputStream(file);
            ois = new ObjectInputStream(fis);
            Object readObject = ois.readObject();
            List<T> obj = (List<T>) readObject;
            System.out.println(obj);
            return obj;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭 fis,ois 等...
        }
    }
    return null;
}

那么我就得到了预期的结果:

// 控制台输出
[1, 2, 3, 4, 5] // --> 这是 System.out.println(obj) 的结果;
[1, 2, 3, 4, 5] // --> 这是 System.out.println(result) 的结果;

我不知道为什么会这样。为什么当我将 result 列表作为参数传递时,我无法获得预期的结果?请帮助我。


<details>
<summary>英文:</summary>

I have a method writing `List&lt;String&gt;` into file like this:

```java
public static void main(String[] args) {
	List&lt;String&gt; data = Arrays.asList(&quot;1&quot;, &quot;2&quot;, &quot;3&quot;, &quot;4&quot;, &quot;5&quot;);
	writeObjectToFile(data, &quot;demo.dat&quot;);
	
	List&lt;String&gt; result = null;
	readObjectFromFile(result, &quot;demo.dat&quot;);
	System.out.println(result);
}

with the writeObjectToFile method:

public static &lt;T&gt; void writeObjectToFile(List&lt;T&gt; obj, String fileName) {
	File file = new File(fileName);
	FileOutputStream fos = null;
	ObjectOutputStream oos = null;

	try {
		fos = new FileOutputStream(file);
		oos = new ObjectOutputStream(fos);
		oos.writeObject(obj);
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// close fos, oos, ... 
	}
}

and readObjectFromFile method:

public static &lt;T&gt; void readObjectFromFile(List&lt;T&gt; obj, String fileName) {
	File file = new File(fileName);
	FileInputStream fis = null;
	ObjectInputStream ois = null;

	if (file.exists()) {
		try {
			fis = new FileInputStream(file);
			ois = new ObjectInputStream(fis);
			Object readObject = ois.readObject();
			obj = (List&lt;T&gt;) readObject;
			System.out.println(obj);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// close fis, ois,...
		}
	}
}

The writing data to file is OK, but the reading step is not working as expected. I got the result list is null:

// console output
[1, 2, 3, 4, 5] // --&gt; this is result of System.out.println(obj);
null            // --&gt; this is result of System.out.println(result);

But when I change the reading method to return a list:

public static &lt;T&gt; List&lt;T&gt; readObjectFromFile(String fileName) {
	File file = new File(fileName);
	FileInputStream fis = null;
	ObjectInputStream ois = null;

	if (file.exists()) {
		try {
			fis = new FileInputStream(file);
			ois = new ObjectInputStream(fis);
			Object readObject = ois.readObject();
			List&lt;T&gt; obj = (List&lt;T&gt;) readObject;
			System.out.println(obj);
			return obj;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// close fis, ois,...
		}
	}
	return null;
}

Then I get the expected result:

// console output
[1, 2, 3, 4, 5] // --&gt; this is result of System.out.println(obj);
[1, 2, 3, 4, 5] // --&gt; this is result of System.out.println(result);

I don't know why is it. Why when I passed the result list as a parameter, I could not get the expected result? Please help me.

答案1

得分: 1

你正在改变它的引用值,Java 是按值传递的,当你将一个对象作为参数传递给一个方法时,Java 会传递一个保存引用值的变量,你不能改变那个值(确切地说,你只能在方法内部改变那个值)。

想象一下,在你将它传递到方法之前,它指向 null。

在方法内部,你试图将它指向另一个对象(分配新的引用值)。
当方法结束时,这个变化将被丢弃,它仍然指向 null。

英文:

You are changing it reference value, Java is pass by value, when you pass an object to a method as a parameter, java pass a variable that keep the reference value, you can't change that value ( correctly, you can change that value just inside method only )

Imagine that it point to null before you pass it into method

Inside method, you are trying to point it to another object ( assign new reference value )
It will be discard when method end, it still point to null

答案2

得分: 0

您的List obj仅是对您在main()中初始化的列表的引用。只要方法正在执行,此引用就在堆栈上。当您将一个新值赋给obj时,obj指向该值。您没有改变result的值,就像您可能期望的那样。您需要做的是类似于

obj.addAll(readObject)
英文:

Your List<T> obj is only a reference to the list you initialised in main(). And this reference is on the stack as long as the method is executing. When you assign a new value to obj, then obj points to that value. You have not changed the value of result, as you might be expecting. What you have to do is something like

obj.addAll(readObject)

huangapple
  • 本文由 发表于 2020年10月3日 01:32:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/64175930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定