为什么使用泛型??????
--java集合有一个缺点—对象进入集合后,该对象的编译类型就变成了Object类型(运行时类型没变)
其优点:带来了很好的通用性.
缺点:集合对元素类型没有任何限制,什么都能放进去,会带来异常.
集合丢失了对象的状态信息 , 集合只知道它盛装的是Object , 因此取出集合元素后通常还需进行强制类型转换.
什么是泛型????????
----允许在定义类,接口,方法时使用类型形参,这个类型形参将在声明变量,创建对象,调用方法时动态地指定.
ArrayList<E>
– 泛型类型ArrayList
– 原始类型E
– 类型参数<>
– 读作”typeof”ArrayList<Integer>
– 参数化的类型Integer
– 实际类型参数
- 参数化类型和原始类型相互兼容
- ?”表示任意类型,使用”?”通配符可以引用各种参数化的类型,可以调用与参数化无关的方法(如size()方法),不能调用与参数化有关的方法(如add()方法)
- 参数化类型不考虑类型参数的继承关系
- ? “任意通配符”
?”表示任意类型,使用”?”通配符可以引用各种参数化的类型,可以调用与参数化无关的方法(如size()方法),不能调用与参数化有关的方法(如add()方法)
-----------设定的类型通配符的上限
List<? extends Shape> 时受限制通配符的例子.
ArrayList<? extends Number > collection1= new ArrayList<Integer >();//编译通过
-----------设定的通配符下限
TreeSet<String> 只要尖括号传入的类型是String的父类型或他本身即可.
------------泛型方法
static void form(Object[] a, Collection<Object> c){
for(Object o: a)
c.add(o);
}
如果一个方法中形参a 的类型或返回值的类型依赖于另一个形参b 则形参 b 类型声明不应该使用通配符——
因为形参 a 依赖 b , b 确定不了 a 也确定不了.
java 8 改进了泛型方法的类型判断能力
1.通过调用方法的上下文来推断类型参数的目标类型
2.在方法调用链中,将判断得到的类型参数传递到最后一个方法 .
擦除:
泛型是提供给javac编译器使用的,限定集合的输入类型,编译器编译带类型说明的集合时会去掉“类型”信息。
当一个具有泛型信息的对象赋给另一个没有反省信息的变量时,所有在尖括号之间的信息都被扔掉.
----使用反射可跳过编译器,往某个泛型集合加入其它类型数据. 只有医用类型才能作为泛型方法的实际参数.
但注意基本类型有时可以作为实参,因为有自动装箱和拆箱。
当一个变量被声明为泛型时,只能被实例变量和方法调用(还有内嵌类型),而不能被静态变量和静态方法调用。因为静态成员是被所参数化的类所共享的,所以静态成员不应该有类级别的类型参数
------- 把泛型变量当成方法的参数,利用Method类的getGenericParameterTypes方法来获取泛型的实际类型参数