/** * 查询用户列表 * @return userList */ public ArrayList<Object> seleteUserList() { initDb(); PreparedStatement pst = null; ResultSet rs = null; ArrayList<Object> userList = null; try { String sql = "SELECT user_id,user_name FROM usertable WHERE user_display = 1"; pst = con.prepareStatement(sql); rs = pst.executeQuery(); userList = new ArrayList<Object>(); while (rs.next()) { Integer userId = rs.getInt("user_id"); String userName = rs.getString("user_name"); UserVo uv = new UserVo(); uv.setUserId(userId); uv.setUserName(userName); userList.add(uv); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { rs.close(); pst.close(); con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return userList; }
还是以代码为例:
1. ArrayList<Object>后面的object什么意思?去掉行不行?
2.根据10行和15行,将10行改为ArrayList<object> userList = new ArrayList<object>();删除15行,行不行?
3.20和21行,改为
uv.setUserId(rs.getInt("user_id"));
uv.setUserName(rs.getString("user_name"));
行不行?
2.根据10行和15行,将10行改为ArrayList userList = new ArrayList();删除15行,行不行?
这样不行,必须在try外边声明 因为你要返回;
3.20和21行,改为
uv.setUserId(rs.getInt("user_id"));
uv.setUserName(rs.getString("user_name"));
行不行?
行。
泛型的目的:参数化类型,并且保证编写代码的正确性和安全性;
1、参数化类型
如我有一个数据结果List,这是一个有序列表,如果没有泛型,我可能这么来实现:
IntList、DoubleList --->每个类型都需要一个
或者
ObjectList --->Object是所有类型的超类,可能造成数据混乱,引起代码错误;
我们知道 List的算法骨架都是一样的,只是操作的数据不一样(如Int、Long……),因此呢,我们把这个数据类型参数化:
List ---->T表示泛型形参,类似于方法的形参
我们使用时可以通过 List Integer就是实参;
这样的好处我们只有一个List数据结构,仅仅是数据不同。
2、编码的安全性和正确性
没有泛型时
List 可以存放任意的Object类型,既Integer、Long等都行,我们可能放入不正确的数据,造成程序异常;
有了泛型之后,我们在写代码时
List<Integer> 只能放Integer类型
3、你的这个List 和List 其实没什么区别,建议改成 List 这样就只能往里放UserVo 这个类型的数据。
标准写法是ArrayList,至于 ArrayList 是泛型,jdk。1.5新特性每一行是一个list集合
因为有2列,如果有一列的话查询的列是什么类型那么
返回就应该是 ArrayList<列的类型>
如果查询2列返回是一个 Object[]
每行记录对应一个 Object[] 第一列就是 Object[0]
如果是 ArrayList while循环要改成下面的:
ArrayList userList = null;
userList = new ArrayList();
while (rs.next()) {
Object[] obj=new Object[2];
obj[0]=rs.getInt("user_id");
obj[1]=rs.getString("user_name");
userList.add(obj);
}
回答你问题1:
删除后面 Object 可以,不过在迭代是时候需要类型转换了 这样写法是jdk1.5新特性,限制存入集合中的类型
回答你问题2:
当然可以直接new 不用声明变量
回答你问题3:写法是可以的
uv.setUserId(rs.getInt("user_id"));
uv.setUserName(rs.getString("user_name"));
问题1. 这种语法叫泛型,是为了限制塞入ArrayList中的类型,后面用的时候就可以直接取用而不用类型转换。删除也可以,只是后面取出来用的时候就要做强制类型转换。
看你这里是装的UserVo ,所以建议写成ArrayList userList = null而不要用Object基类;
问题2.根据10行和15行,将10行改为ArrayList userList = new ArrayList();删除15行,行不行?
行肯定是行的!将声明和实例化放在一句是没问题的。但一般是提倡先声明,使用的时候再实例化,因为如果你是在循环体里面每次都声明和实例化一次是会消耗内存资源的,而先在循环体外面声明一次,循环体里面实例化会节约部分资源。所以,你这里的声明和实例化都没有在循环体里的话,按你说的行!
问题3.20和21行,改为
uv.setUserId(rs.getInt("user_id"));
uv.setUserName(rs.getString("user_name"));
行不行?
行肯定是行的!只是将你原有的17,18,20,21行整成了你现在的两句,效果当然是一样的,只是将每两句写成了一句而已。但原有那种写法代码可读性强一些,也就是美观一些。
仅供参考~
<%=((UserVo)userList.get(i)).getUserId() %>
这个是遍历一个集合的方法
因为你在后台代码中写:
while (rs.next()) {
Integer userId = rs.getInt("user_id");
String userName = rs.getString("user_name");
UserVo uv = new UserVo();
uv.setUserId(userId);
uv.setUserName(userName);
userList.add(uv);
}
UserVo uv = new UserVo();
uv.setUserId(userId);
uv.setUserName(userName);
Object是所有类的父类当然也是 UserVo 的父类,
也就是ArrayList标准写法是
ArrayList因为你使用的是ArrayList 所以又了你在jsp上类型转换
<%=((UserVo)userList.get(i)).getUserId() %>
把ArrayList 集合中的存入的元素,(你代码中add是 UserVo 对象 )
所以遍历需要转换
Homework?
Q1:这是运用了jdk1.5的新特性泛型 说明这个list中只能装Object类型的对象 装其他的不行
可以去掉 这个只是编译(javac)的时候做检查的
防止你在获取list中的 数据的时候转型出现错误
Q2: 可以 但是尽量做到将变量的初始化延迟到使用的时候 这样好一些 以免浪费不必要的内存
Q3: 这个完全没问题 主要是方便理解和增强可读性就行 这个没有要求
补充问题: 是这样的 首先 你应该了解jsp与servlet的关系 jsp是一个特殊的servlet 在输出jsp页面的时候
编译器先将其转换为servlet 然后再servlet的service方法中进行out。put()的一些输入
(这个你可以看tomcat 下的\work\Catalina\。。东西 都是jsp编译的servlet )
<%= %>这个作用是将里面的内容按照java代码处理 (“=”号的意思是输出的意思)
1.Object 是指查出来的Model对象(这里指UserVo),去掉可以,去掉默认的也是Object.
2.修改第十行,删除第十五行可以。但是这样的话,返回值就需要判断。
3.可以。
补充问题,是获得UserId。
我一般这样写,参考参考下
List中有个Object是泛型,泛型只是使用一个符号来代替类型。在编译class时编译器自动推导你需要的类型,并替换。
[code="java"]
public void close(Object... args) {
for (Object arg : args) {
if (arg instanceof Connection) {
try {
((Connection) arg).close();
} catch (SQLException e) {
}
} else if (arg instanceof Statement) {
try {
((Statement) arg).close();
} catch (SQLException e) {
}
} else if (arg instanceof ResultSet) {
try {
((ResultSet) arg).close();
} catch (SQLException e) {
}
}
}
}
public List seleteUserList() {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
List userList = new ArrayList();
try {
String sql = "SELECT user_id,user_name FROM usertable WHERE user_display = 1";
pst = con.prepareStatement(sql);
rs = pst.executeQuery();
while (rs.next()) {
UserVo uv = new UserVo();
uv.setUserId(rs.getInt("user_id"));
uv.setUserName(rs.getString("user_name"));
userList.add(uv);
}
} catch (SQLException e) {
throw new IllegalStateException("无法处理异常:" + e, e);
} finally {
close(rs, pst, con);
}
return userList;
}
[/code]
首先,你这段代码是有问题的,while (rs.next()) { },这代表你一直循环下一个记录,最后出现空指针,当然最后你catch异常了,因此结果是能得到的,但这会损耗很大的开销。
其次,定义的List和不用泛型是没有区别的,因为Object是原生对象,所有类都继承Object,可以直接使用List,这才是泛型的精髓。
第三,数据库的查询,一般很少有人每次查询都创建连接的,一般都是使用连接池,减少创建的时间和连接的限制。
又白忙了。。。。