Java中内部和外部循环定义对象的不同之处

时间:2012-12-15 22:13:25

标签: java loops

我今天在部分代码中苦苦挣扎,从文件中读取一些数据并将它们作为属性添加到对象中(我知道如何在没有这个麻烦的情况下添加/读取文件中的对象但是想要这样做这样)如下:

文件是这样的:

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

我刚刚在while循环中移动了Staff tmpstaff = new Staff();,它显示了它应该是什么。

为什么会这样?我在这里阅读 - 在循环内部或外部定义变量(好吧,这里是一个对象)没有任何区别。

4 个答案:

答案 0 :(得分: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();
     ...

是等价的。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

你可以在循环外定义变量,但你必须在循环中实例化一个新的Object,所以看起来像这样:

Staff tmpStaff
while((tmp = inputfile.readLine()) != null){
tmpStaff = new Staff();
[additional Code here]
}

答案 3 :(得分:2)

如果你想在循环的每次传递中创建一个新的Staff,那么你必须在使用之前在循环内部进行创建。

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

只有在使用new关键字时才会创建新对象。