两个概念:
<T> T类型形参
<String> String是实际类型参数
并不存在泛型类
我们所说的泛型类是逻辑上的,物理上是不存在,
List<String> a =
new ArrayList <String>();
List<Integer> b = new ArrayList <Integer>();
System.out.print(a.getClass() == b.getClass());//打印的结果是 "true"
List<Integer> b = new ArrayList <Integer>();
System.out.print(a.getClass() == b.getClass());//打印的结果是 "true"
因为List<String> 和 List<Integer>是同种类,他们在内存中是占用同一块内存,
所有静态域,静态方法,静态初始化块,是不允许使用泛型的。
static T info;
public static T getCount(){}
//以上两个都是错误的,静态XX是不允许使用泛型,因为他们是使用一块内存的,作为类变量和类方法是共享的,所以不能因T的改变而改变,故使用泛型编程是不合法的。
public static T getCount(){}
//以上两个都是错误的,静态XX是不允许使用泛型,因为他们是使用一块内存的,作为类变量和类方法是共享的,所以不能因T的改变而改变,故使用泛型编程是不合法的。
从泛型类派生子类
不能带类型形参。只能带实际类型参数。注意:String 是 Object的子类。但是 List<String> 不是 List<Object>的子类。
数组和泛型
数组的父类只能是数组或者Object有类 A BB extends AB[] 不是 A或者B的子类B[] 是A[]的子类 也是Object的子类G<A> 和G<B>G<B> 不是G<A> 的子类,这是泛型在继承上与数组的不同之处
类型通配符 "?"
利用类型通配符目的是来表示泛型的父类
例如: List<?> 是List<T>(T是任何类型) 的父类。 "?"是可以匹配任何类型的。
List<?> 只是用来表示父类,List<?> a a.add(new Object()); 这个是不合法的,因为根本就不知道a 里面是什么类型,所以不能进行add操作。
设定通配符的上限 List<? extends shaps>
List<? extends shaps> 缩小了? 的范围 只能是shaps本身,或者是shaps的派生子类。
public void
do (List<?> shaps){
Shaps myShaps =(Shaps) shaps.get(0);//要进行类型转换,比较繁琐
myShaps.paint();//调用shaps的一个方法;
}
public void do (List<? extends Shaps> shaps){
shaps.get(0).paint();//不用进行强制类型转换,利用多态,shaps 是Shaps 或者Shaps子类实例,都可以不用强制类型转换就可以调用paint()方法。
}
Shaps myShaps =(Shaps) shaps.get(0);//要进行类型转换,比较繁琐
myShaps.paint();//调用shaps的一个方法;
}
public void do (List<? extends Shaps> shaps){
shaps.get(0).paint();//不用进行强制类型转换,利用多态,shaps 是Shaps 或者Shaps子类实例,都可以不用强制类型转换就可以调用paint()方法。
}
注意:同 "?"一样 "List<? extends a> " a.add(new Shaps()); 也是不合法的,因为不能准确知道子类类型。
总之:使用 通配符"?" 类型就是未知,所以不能add进去
设定类型形参的上限 List<T extends shaps>
List<T extends shaps & java.io.serializable>
还可以这样子,用&实现多个限制,