日期:2014-05-20  浏览次数:20776 次

一个有点奇怪的ArrayList的问题,请帮忙看一看。
有类如下
//a   simple   bean
class   sbean   {
      String   username;
//Getter   and   Setter   省略。
}
连接数据库取数据
库数据如下:
username
chen8m
kok
admin
//从数据库里取数据存在BEAN里面,再放在ArrayList
里面,但最后取出来username却变成了全部都是admin了。

Class.forName( "com.mysql.jdbc.Driver ");

String   url   =   "jdbc:mysql://localhost:3306/strust ";
String   user   =   "root ";
String   password   =   "root ";

Connection   con   =   DriverManager.getConnection(url,user,password);

Statement   stat   =   con.createStatement();

String   sql   =   "select   *   from   userInfor ";

ResultSet   result   =   stat.executeQuery(sql);
ArrayList   alluser   =   new   ArrayList();
userInfor   temp   =   new   userInfor();
while   (result.next())   {
System.out.print(result.getString( "username "));
System.out.print( " ");
temp.setUsername(result.getString( "username "));
alluser.add(temp);
}
for   (int   i=0;   i <alluser.size();   i++)   {
userInfor   t   =   (userInfor)alluser.get(i);
System.out.println(t.getUsername()+ "-- "+i);
}  
}
//但是下面的代码改变了一点点就OK了。
Class.forName( "com.mysql.jdbc.Driver ");

String   url   =   "jdbc:mysql://localhost:3306/strust ";
String   user   =   "root ";
String   password   =   "root ";

Connection   con   =   DriverManager.getConnection(url,user,password);

Statement   stat   =   con.createStatement();

String   sql   =   "select   *   from   userInfor ";

ResultSet   result   =   stat.executeQuery(sql);
ArrayList   alluser   =   new   ArrayList();
//在这里做改变,把TEMP放在了循环里就OK了。
while   (result.next())   {
userInfor   temp   =   new   userInfor(); System.out.print(result.getString( "username "));
System.out.print( " ");
temp.setUsername(result.getString( "username "));
alluser.add(temp);
}
for   (int   i=0;   i <alluser.size();   i++)   {
userInfor   t   =   (userInfor)alluser.get(i);
System.out.println(t.getUsername()+ "-- "+i);
}  
}
打字的框好小啊,都不知道问题有没有说清楚,
请看到的高手帮忙耐心看看,
问题是解决了,但就是不明白是为什么。
上一段代码调试的时候,明明都存在LIST里是对的
就是存到最后一个整个LIST就都变了。
望高手帮忙了,小弟在此谢过。




------解决方案--------------------
调试的时候里面的值当然是变的啊,对同一个实例而言,你存放在ArrayList里面的始终是同一个对象啊!
------解决方案--------------------
Java 中的对象是引用类型的,通俗点说,变量名中存放的是其数据的内存地址,它的值是存放在另外一块空间上的。

在第一段程序中,List 添加了很多的 temp(实际上添加了 temp 的内存地址),也就是说,List 中添加了很多相同的 temp,但是 temp 的 username 最终是指向最后一个的,所以前面存放在 List 中的 temp 的 username 值也就随之改变了,具体的引用关系参见下图(空白部分只能用.代替)。

-------
list(0) --------+
------- ........|.. ------- ...... ----------
list(1) --------+--> temp --------> username
------- ........|.. ------- ...... ----------
list(n) --------+
-------


而第二段程序中,temp 的作用范围仅在 { } 内,每循环一次就重新生成不同的对象,所以添加到最后也是不同的,这是正确的方法,为了与上一段进行比较,引用关系如下: