我今天在部分代码中苦苦挣扎,从文件中读取一些数据并将它们作为属性添加到对象中(我知道如何在没有这个麻烦的情况下添加/读取文件中的对象但是想要这样做这样)如下:
文件是这样的:
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();
,它显示了它应该是什么。
为什么会这样?我在这里阅读 - 在循环内部或外部定义变量(好吧,这里是一个对象)没有任何区别。
答案 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关键字时才会创建新对象。