0

我今天正在努力处理我的部分代码,以从文件中读取一些数据并将它们作为其属性添加到对象中(我知道如何在文件中添加/读取对象而不会有这种麻烦,但我想这样做)如下:

文件是这样的:

111,john,23.1
222,jack,22.5
234,adam,12.8

我试图使用以下方法读取此文件:

public ArrayList<Staff> LoadAllStaffs(){
    ArrayList<Staff> staffs = new ArrayList<Staff>();
    File file = new File(stafffile);
    Staff tmpstaff = new Staff();
    try {
        BufferedReader inputfile = new BufferedReader(new FileReader(stafffile));
        String tmp;
        while((tmp = inputfile.readLine()) != null){
            StringTokenizer st = new StringTokenizer(tmp , ",");
            tmpstaff.setID(Integer.valueOf(st.nextToken()));
            tmpstaff.setFirstName(st.nextToken());
            tmpstaff.setSalary(Double.valueOf(st.nextToken()));
            staffs.add(tmpstaff);
            }
        } 
    catch (IOException e) {
    }
    return staffs;
}

使用println返回的输出ArrayList

234,adam,12.8
234,adam,12.8
234,adam,12.8

我只是移动了Staff tmpstaff = new Staff();while循环内部,它显示了它应该做什么。

为什么会这样?我读到——即使在这里——在循环内部或外部定义变量(嗯,这里是一个 Object )没有任何区别。

4

4 回答 4

5

您不是Staff在循环内创建新实例,而是在所有迭代中重用同一个实例。因此,您覆盖这些值并添加相同的对象。

移动

Staff tmpstaff = new Staff();

到循环内的第一行。

更新:为了解决Vash的评论,这里的问题可以解释为,如果要存储 3 个对象,则需要创建这样的 3 个对象。您可以重用引用tmpstaff变量),并且在定义它的地方有效地重用它并不重要(只要对它的所有引用都在同一范围内。但是您必须创建 3 个对象,这意味着 3 个new命令。

更新2:为了简单起见,文字I read -even here- that defining variables (well, here its an Object ) inside or outside loops doesn't make any difference.意味着

File file = new File(stafffile);
Staff tmpstaff = null; // or simpler, Staff tmpstaff;
try {
   ...
   while((tmp = inputfile.readLine()) != null){
     tmpstaff = new Staff();
     ...

   while((tmp = inputfile.readLine()) != null){
     Staff tmpstaff = new Staff();
     ...

是等价的。

于 2012-12-15T22:15:06.847 回答
2

操作员new负责称为实例的“对象创建”。因此,当您在循环之外创建他时,您只有一个实例,即您修改每个循环运行。在循环内创建该对象时,每次运行都有单独的实例。

于 2012-12-15T22:20:01.670 回答
2

Java 通过对对象的引用进行操作。因为您只创建了一个 Staff() 对象,所以只有一个引用。因此,在 while 循环中,您只需更改 Object 的属性并将相同的 Reference 添加到 List 中 3 次。

您可以在循环外定义变量,但您必须在循环内实例化一个新对象,使其看起来像这样:

Staff tmpStaff
while((tmp = inputfile.readLine()) != null){
tmpStaff = new Staff();
[additional Code here]
}
于 2012-12-15T22:20:03.590 回答
2

如果您想在循环的每个通道上创建一个新的 Staff,那么您必须在使用它之前在循环内部进行创建。

像你一样在循环之外完成,你确实创建了一个新的 Staff,但每次都在使用它。

仅当使用 new 关键字时才会创建新对象。

于 2012-12-15T22:20:51.837 回答