免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1737 | 回复: 0
打印 上一主题 下一主题

java泛型笔记(1) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-27 16:01 |只看该作者 |倒序浏览

本来jdk5之前有java.util.List这个Interface

是这么用的:
List myIntList = new LinkedList(); // LinkedList是实现了List Interface的类
myIntList.add(new Integer(0));
Integer x = (Integer)myIntList.iterator().next();

这里myIntList其实可以myIntList.add(new Object());因为声明语句就没有写出该List到底支持什么。
所以myIntList.iterator().next()返回的只能是Object,它并不知道这里面装的到底是什么具体的类。
因为这个List里既可能有Integer对象,也可能有Double对象~

为了不要(Integer)这个强制转换,我们有了这个:
List myIntList = new LinkedList();
这个时候,Integer x = (Integer)myIntList.iterator().next();就可以去掉强制转换写成
Integer x = myIntList.iterator.next();
因为编译器确实知道了myIntList里放的就是Integer,不会是其他。

这个地方要注意
List myIntList = new LinkedList();
这句话的真正含义
右边是创建一个LinkedList的对象,然后把引用给左边一个叫myIntList的名字。
理解下面两个例子就知道了:
List myIntList = new LinkedList(); //警告,不出错 myIntList可以add(Object)
List myIntList = new LinkedList(); //警告,不出错 myIntList只能add(Integer)
List myIntList = new LinkedList(); // 出错

事情到这里,看似所有问题都解决了,但是不尽然。慢慢道来:
class Shape {
public void say();
};

class Circle extends {
public void say() {
System.out.println("i am a circle");
}
};
通过上面,我们可以
Shape shape = new Circle();
shape.say(); // i am a circle.
这里表明,父类可以代表子类。
但是
List却不是List的父类

如果有个函数:
public void sayAll(List list) {
for(Shape s : list) {
s.say();
}
}
那么这个函数不能被这样调用:
List circleList = new List();
sayAll(circleList);
只能被这样调用:
List shapeList = new List();
sayAll(shapeList);

##这里详细解释为什么List不能代表List
看下面代码就知道:
List circleList = new List();
List shapeList = circleList;
shapeList.add(new Shape());
circleList.iterator().next(); //出错。

那么怎么解决这个问题?可以这样解决:
public void sayAll(List list) {
for(Object s : list) {

}
}
具体我们刚才讨论的Shape和Circle的问题可以这样写:
public void sayAll(List list) {
for(Shape s : list) {
s.say();
}
}
其中public void sayAll(List list) 就是public void sayAll(List list) 的意思

这个例子说明,List才是List和List的“父类”,可以传递引用。
也说明List是List的“父类”,可以传递引用,而不是List的“父类”,因为Integer extends Shape不成立

我们再来看一个例子来加深印象,结束这个话题。然后讨论新话题。
class Person {}
class Student extends Person{}
public class Census {
public static void addRegistry(Map registry) { ... }
};

Map allDrivers = ...
Census.add(allDrivers);

我们下一个话题,先由这个引起:
我们说过,如果
List是List的“父类”
那么会出现一个矛盾:
List circleList = new List();
List shapeList = circleList; //错误
shapeList.add(new Shape());
circleList.iterator().next(); //出错。

那么List确实是List的“父类”,会有这个矛盾不?同样有,如下:
List circleList = new List();
List list= circleList; //正确
list.add(new Shape()); //错误
为什么list不能加新元素?
因为list里的元素类型已经定义好了,是?,不是任何类型,所以不能加入任何类型的元素。
所以如下方法是不能使用的:
static void fromArrayToCollection(Object[] a, Collection c) {
for (Object o : a) {
c.add(o); // compile time error 因为c不能加入元素
}
}

但是我们想要在List里加入元素如何弄呢?一个例子概括如下:
static  void fromArrayToCollection(T[] a, Collection c) {
for (T o : a) {
c.add(o); // correct
}
}
那么这样,c这个Collection就能加入东西了,加入的东西必须是T类,看例子:
Object[] oa = new Object[100];
Collection co = new ArrayList();
fromArrayToCollection(oa, co);// T inferred to be Object

String[] sa = new String[100];
Collection cs = new ArrayList();
fromArrayToCollection(sa, cs);// T inferred to be String
fromArrayToCollection(sa, co);// T inferred to be Object

Integer[] ia = new Integer[100];
Float[] fa = new Float[100];
Number[] na = new Number[100];
Collection cn = new ArrayList();
fromArrayToCollection(ia, cn);// T inferred to be Number
fromArrayToCollection(fa, cn);// T inferred to be Number
fromArrayToCollection(na, cn);// T inferred to be Number
fromArrayToCollection(na, co);// T inferred to be Object
fromArrayToCollection(na, cs);// compile-time error


到现在为止,上面一共讲了两个jdk1.5中新的事物
List list = new LinkedList(); // wildcards
static  void fromArrayToCollection(T[] a, Collection c)

那么看下面两个例子,他们做的事情都是一样的,但是分别用了这两个方法:
interface Collection {
public boolean containsAll(Collection c);
public boolean addAll(Collection}

interface Collection {
public  boolean containsAll(Collection c);
public  boolean addAll(Collection c);
}

他们都做两件事:判断任意类的容器是不是在本身这容器里。加入E子类的容器到本身的容器里。

也可以同时都用上两个新东西:
class Collection {
public static  void copy(List dest, List src){}
}

或者写成
class Collection {
public static  void copy(List dest, List src){}
}

作为总结这两个新的java特性,举出一个复杂例子:

static List> history = new ArrayList>();

public void drawAll(List shapes) {
history.addLast(shapes);
for(Shape s : shape) {
s.draw(this);
}
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/105041/showart_2105590.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP