e代剑客——温柔一刀
生活就像海洋,只有意志坚强的人,才能到达彼岸
::
首页
::
新随笔
::
联系
::
聚合
::
管理
::
76 随笔 :: 7 文章 :: 215 评论 :: 0 Trackbacks
随笔分类
(78)
Agile(3)
(rss)
java相关(33)
(rss)
ROR(2)
(rss)
web相关(1)
(rss)
其他(11)
(rss)
开源框架(19)
(rss)
数据库相关(8)
(rss)
生活点滴(1)
(rss)
随笔档案
(76)
2010年10月 (1)
2007年12月 (3)
2007年7月 (1)
2007年4月 (1)
2007年2月 (4)
2006年12月 (2)
2006年11月 (1)
2006年10月 (9)
2006年9月 (3)
2006年8月 (27)
2006年7月 (14)
2006年6月 (1)
2006年4月 (9)
java源码
java examples
java学习源代码检索中心
java开源大全
spring源码学习
友情连接
e代剑客—JavaEye
(rss)
开发文档
hibernate中文文档
Java2 API 规范
javascript参考手册
MySQL中文参考手册
Spring参考手册
spring进阶-IT实验室
XPath 教程
搜索
最新评论
1. re: Java应用iText动态生成PDF文件
e21e12eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
--eq23r
2. re: Toad for oracle 教程[未登录]
多谢!!!
--啊啊
3. re: Toad for oracle 教程
谢了
--后来者
4. re: Toad for oracle 教程
好人多
--hzlxm
5. re: Toad for oracle 教程
谢谢!
--stophy
阅读排行榜
1. Toad for oracle 教程(11272)
2. spring 生成Excel和PDF文件(7308)
3. javascript获取客户端网卡MAC地址和IP地址和计算机名(7282)
4. 最简单的iBatis入门例子(6603)
5. JXL操作Excel(6467)
评论排行榜
1. Toad for oracle 教程(109)
2. spring、ibatis控制oracle分页的问题 (23)
3. 最简单的iBatis入门例子(16)
4. 德比软件(DerbySoft)诚聘java工程师(上海)(10)
5. spring 生成Excel和PDF文件(7)
java 范型编程
1.一个简单的范型示例
在以前,你可能遇到过这样的代码:
1
List list
=
new
LinkedList();
2
3
list.add(
"
a
"
);
4
5
list.add(
"
b
"
);
6
7
list.add(
"
c
"
);
8
9
String name
=
(String)list.iterator.next();
注意,第三行需要强制转换。而使用范型:
1
2
List
<
String
>
list
=
new
LinkedList
<
String
>
();
3
4
list.add(
"
a
"
)
5
6
list.add(
"
b
"
);
7
8
list.add(
"
c
"
);
9
10
String name
=
list.iterator.next();
11
12
这里将list声明成String类型的List。List是有一个类型参数的范型接口。这个例子中类型参数是String。
2.定义简单的范型
看j2se5.0中List和Iterator接口的实现(片断):
1
2
public
interface
List
<
E
>
3
4
{
5
6
void
add(E x);
7
8
Iterator
<
E
>
iterator();
9
10
}
11
12
public
interface
Iterator
<
E
>
13
14
{
15
16
E next();
17
18
boolean
hasNext();
19
20
}
21
22
上面的代码我们比较熟悉,但是其中增加了尖括号。尖括号中的内容定义了接口List和Iterator的形式类型参数。类型参数可以用在范型声明中,如类和接口的声明。
一旦声明了范型,你就可以使用它。在上面的例子中使用了List<String>。这里使用String是实参,代替了形参E。如果使用List<Integer>,则用实参Integer代替了形参E。
不管List<Integer>还是List<String>,它们的类只有一个。考虑下面的代码:
1
2
List
<
String
>
list1
=
new
LinkedList
<
String
>
();
3
4
List
<
Integer
>
list2
=
new
LinkedList
<
Integer
>
();
5
6
System.out.println(list1.getClass()
==
list2.getClass());
7
输出结果为true。
一般来说,形式类型参数都是大写,尽量使用单个字母,许多容器类都使用E作为参数。
3.范型和继承
考虑下面的代码,你认为它会出错吗?
1
2
String s =
"
xxx@gmail.com
"
;
3
4
Object o
=
s:
5
当然,String类继承Object类,这样做不会出错。但下面的代码呢?
1
List
<
String
>
s
=
new
LinkedList
<
String
>
();
2
3
List
<
Object
>
o
=
s;
4
编译出错!
是的,List<Object>和List<String>没有继承关系。
4.通配符
考虑下面一个方法:
1
2
public
void
printCollection(Collection
<
Object
>
c)
3
4
{
5
6
for
(Object o:c)
7
8
{
9
10
System.out.printf(
"
%s%n
"
,o);
11
12
}
13
14
}
15
事实上,上面这个方法并不通用,它只能打印Collection<Object>类型的集合,象其他的如Collection<String>、Collection<Integer>并不能被打印,因为对象类型不一致。
为了解决这个问题,可以使用通配符:
1
2
public
void
printCollection(Collection
<
?
>
c)
3
4
{
5
6
for
(Object o:c)
7
8
{
9
10
System.out.printf(
"
%s%n
"
,o);
11
12
}
13
14
}
15
16
Collection<?>被称作未知类型的集合。问号代表各种类型。
上面的读取集合中的数据时,我们采用Object类型。这样做时可以的,因为不管未知类型最终代表何种类型,它的数据都继承Object类,那么再考虑一下下面的代码:
1
2
Collection
<?>
c
=
new
ArrayList
<
String
>
();
3
4
c.add(
new
Object());
5
6
这样做时错误的,因为我们不知道?代表何种类型,所以我们不能直接将Object增加到集合中,这会出现类型不匹配的情况。
5.有限制的通配符
考虑下面的代码
1
2
class
Man
3
4
{
5
6
public
String name
=
""
;
7
8
}
9
10
class
GoodMan
extends
Man
11
12
{
13
14
public
String name
=
""
;
15
16
}
17
18
class
BadMan
extends
Man
19
20
{
21
22
public
String name
=
""
;
23
24
}
25
26
考虑下面的范型方法:
1
2
public
void
printName(List
<
Man
>
men)
3
4
{
5
6
for
(Man man:men)
7
8
{
9
10
System.out.println(
"
姓名:
"
+
man.name);
11
12
}
13
14
}
15
16
这个范型方法只能显示List<Man>类型的数据,下面的代码允许显示Man和它的子类。
1
2
public
void
printName(List
<
?
extends
Man
>
men)
3
4
{
5
6
for
(Man man:men)
7
8
{
9
10
System.out.println(
"
姓名:
"
+
man.name);
11
12
}
13
14
}
15
16
这里使用? extends Man代替Man,表明接受任何Man的子类做为参数。
和前面的代码类似,下面的代码也是不正确的:
1
2
public
void
adman(List
<?
extends
Man
>
men)
3
4
{
5
6
GoodMan good
=
new
GoodMan();
7
8
good.name
=
"
zhupan
"
;
9
10
men.add(good);
11
12
}
13
14
原因也很简单,因为?代表一切继承Man的类,你并不能保证就一定时GoodMan类。
和这种用法类似:
1
2
public
void
adman(List
<?
super
GoodMan
>
men)
3
4
{
5
6
GoodMan good
=
new
GoodMan();
7
8
good.name
=
"
zhupan
"
;
9
10
men.add(good);
11
12
}
13
6.范型方法
考虑下面的代码,我们将一个数组的内容加到一个集合中
1
2
public
void
copyArrayToCollection(Man[] men, Collection
<?>
c)
3
4
{
5
6
for
(Man man:men)
7
8
{
9
10
c.add(man);
11
12
}
13
14
}
15
16
这段代码时错的!
因为我们并不知道集合C的类型,所以不能将Man类型的数据加到集合中。
可以使用范型方法解决:
1
2
public
<
T
>
void
copyArrayToCollection(T[] men, Collection
<
T
>
c)
3
4
{
5
6
for
(T man:men)
7
8
{
9
10
c.add(man);
11
12
}
13
14
}
15
这里T时一个形式类型参数。
何时该采用通用方法?何时该采用通配符?
考虑下面的例子:
1
2
interface
Collection
<
E
>
3
4
{
5
6
public
boolean
containsAll(Collection
<?>
c);
7
8
public
boolean
addAll(Collection
<?
extends
E
>
c);
9
10
}
11
12
改写成通用方法
1
2
interface
Collection
<
E
>
3
4
{
5
6
public
<
T
>
boolean
containsAll(Collection
<
T
>
c);
7
8
public
<
T
extends
E
>
boolean
addAll(Collection
<
T
>
c);
9
10
}
11
12
然而,在这里每个方法T只使用了一次,返回值不依赖形式参数,其他参数也不依赖形式参数。这说明实参被用作多态,这种情况下就应该用通配符。
posted on 2006-08-14 10:16
温柔一刀
阅读(635)
评论(1)
编辑
收藏
所属分类:
java相关
评论
#
re: java 范型编程
2006-08-14 10:31
testtesttest
test
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
相关文章:
德比软件(DerbySoft)诚聘java工程师(上海)
jpivot中输出pdf打印汉字、excel导出中文方法
Ant+Tomcat自动部署的小问题
FCKeditor-2.3在线编辑器,可以直接用的(java版)
Eclipse快捷键指南
Java应用iText动态生成PDF文件
将Excel文件内容写入到数据库
JXL操作Excel
件上传组件commons-fileupload用户指南
随机生成验证码
Powered by:
BlogJava
Copyright © 温柔一刀
联系偶
zhupanjava@gmail.com
温柔一刀