1) 一句话总结泛型的和核心。
就是类装载类型的参数化。类型是:比如ArrayList<E> , E已经参数化了。E已经是ArrayList中的一部分了,所以当
ArrayList<Boolean>
ArrayList<Integer>
list1=list2 ;
2)相关语法:
- 可以加多个类型参数,用逗号隔开。比如 Generic<T,E>
- 不能创建一个泛型数组。比如 T[] objectArr = new T[10] ; 语法上是不允许的。解决方式是new一个Object数组然后强行转换为T数组:T[] objectArr=(T[])new Object[10];
- 当然T也可以是一个泛型,比如 ArrayList<E> E可以代表一个自己定义的泛型比如 Generic<T> 。所以叫做泛型中包括泛型。
- JDK1.5中所有的集合类都重写为泛型了。
3)限制泛型中的引用类型。
在定义泛型的类别是,默认情况下可以使用任何类来定义泛型中的类型。如ArrayList<T>,T可以是任何类型。当然也可以限制T类型,使用extends关键字来制这个类的装载类型。
在实例化泛型的引用类别时(就是这个引用能够引用什么类别时),可以使用 ? 比如要实现下面的需求让ge1=ge2,
Generic<? extends List> ge1; Generic<? extends List> ge2 ;
ge1= new Generic<ArrayList>();
ge2=new Generic<LinkedList>();
这时候就可以使 ge1=ge2; 同时可以使用 <? super List> 表示List上面的类。
注意:在使用<?>或者<? extends Object>时这两个相同,意味着该引用只能通过赋值的方式(增加)或者通过删除的方式ge.set(null);但不能增加它的信息 比如ge.set(new ArrayList<String>()); 因为违反了泛型的初衷。
上面的总结可能比较含糊,看看代码和代码的注释就明白了。
- import java.util.ArrayList;
- import java.util.LinkedList;
- import java.util.List;
- public class TestGeneric<t> {
- private T foo ;
- public T getFoo() {
- return foo;
- }
- public void setFoo(T foo) {
- this.foo = foo;
- }
- public static void main(String... args){
- // 在类声明时上面的T表示这个类可以装载什么类型 如果类名改变为 TestGeneric<t extends="" list="">
- // 说明只能装载List的子类别
- // 而TestGeneric<?> 则表明了 这个类的引用可以指向什么样的类型,看下面的例子
- // 如果是这样的话就会报错,因为ge只能指向 TestGeneric<ArrayList>()
- // TestGeneric<ArrayList> ge= new TestGeneric<ArrayList>();
- // ge = new TestGeneric<LinkedList>();
- //但是如果这样ge就可以指向TestGeneric<ArrayList> 和TestGeneric<LinkedList>和
- //TestGeneric<Object>(); 以及任何Object的子类
- TestGeneric<?> ge= new TestGeneric<arraylist>();
- ge= new TestGeneric
- <linkedlist>();
- ge = new TestGeneric<object>();
- //但是如果只想指向实现了List接口的类,可以使用 <? extends List>
- TestGeneric<? extends List> ge1= new TestGeneric<ArrayList>();
- ge1 = new TestGeneric<LinkedList>();
- // ge1 = new TestGeneric<Object>(); 会报错
- // 同时还可以指定引用的父类,说明ge2只能指向TestGeneric所装载的类的List的上层类别
- TestGeneric<? super List> ge2 = new TestGeneric<Object>();
- //关于赋值
- TestGeneric<String> ge3 = new TestGeneric<String>();
- ge3.setFoo("Hello World.....");
- TestGeneric<?> ge4 = new TestGeneric<string>();
- ge4=ge3;
- ge3.getFoo(); //是正确的
- // ge4.setFoo("String"); 但是set就会编译错误,因为ge4.set(?) 是一个问号类型,这样当
- // get的时候就会不知道其明确的类型,这违反了 泛型的初衷
- }
- }
- </string></object></linkedlist></arraylist></t></t>