技术开发 频道

java泛型笔记(1)

  我们下一个话题,先由这个引起:我们说过,如果List是List的“父类”,那么会出现一个矛盾:

List<Circle> circleList = new List<Circle>();

List
<Shape> shapeList = circleList; //错误

shapeList.add(
new Shape());

circleList.iterator().next();
//出错。

  那么List确实是List的“父类”,会有这个矛盾不?同样有,如下:

List<Circle> circleList = new List<Circle>();

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 <T> void fromArrayToCollection(T[] a, Collection<T> c) {

      
for (T o : a) {

c.add(o);
// correct

      }

}

  那么这样,c这个Collection就能加入东西了,加入的东西必须是T类,看例子:

Object[] oa = new Object[100];

Collection
<Object> co = new ArrayList<Object>();

fromArrayToCollection(oa, co);
// T inferred to be Object



String[] sa
= new String[100];

Collection
<String> cs = new ArrayList<String>();

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
<Number> cn = new ArrayList<Number>();

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<? extends Parent> list = new LinkedList<Child>(); // wildcards

static <T> void fromArrayToCollection(T[] a, Collection<T> c)

   那么看下面两个例子,他们做的事情都是一样的,但是分别用了这两个方法:

interface Collection<E> {

public boolean containsAll(Collection<?> c);

public boolean addAll(Collection<? extends E) c);        

}

interface Collection<E> {

public <T> boolean containsAll(Collection<T> c);

public <T extends E> boolean addAll(Collection<T> c);

}

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

  也可以同时都用上两个新东西:

class Collection {

public static <T> void copy(List<T> dest, List<? extends T> src){}

}

   或者写成

class Collection {

public static <T,S extends T> void copy(List<T> dest, List<S> src){}

}

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

static List<List<? extends Shape>> history = new ArrayList<List<? extends Shape>>();

public void drawAll(List<? extends Shape> shapes) {

history.addLast(shapes);

for(Shape s : shape) {

s.draw(
this);

}

}
0
相关文章