本帖最后由 塞肥肥塞牙人 于 2014-9-6 11:40 编辑
只要带有<>的类或者接口,都属于带有类型参数的类或者接口,在使用这些类或者接口时,必须给<>中传递一具体的引用数据类型。
2.1.将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题。
3.泛型技术:其实应用在编译时期,是给编译器使用的技术,到了运行时期,泛型就不存在了。为什么? 因为泛型的擦除:也就是说,编辑器检查了泛型的类型正确后,在生成的类文件中是没有泛型的。
4.泛型的补偿:因为存储的时候,类型已经确定了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,在内部进行一次转换即可, 所以使用者不用再做转换动作了。
只有引用类型才能应用在泛型变量中,8大基本数据类型不行
原始类型可以转换为带有泛型的类型:如:ArrayList<Integet> list = new ArrayList();//编译通过但会报警告.
带有泛型类型的变量之间不能转换:如:ArrayList<Integet> list = new ArrayList<Object>();//会报编译错误
ArrayList<Object> list = new ArrayList<Integet>();//也会报编译错误
当类中的操作的引用数据类型不确定的时候,以前用的Object来进行扩展的,现在可以用泛型来表示。这可以避免强转的麻烦,而且将运行问题转移到的编译时期。
可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使Object类中的功能。那么可以用 ? 通配符来表未知类型。
6.1上限:?extends E:可以接收E类型或者E的子类型对象。
ArrayList<? extends Number > list = new ArrayList<Integer>();//正确,因为Number是Integer的父类
上限什么时候用:往集合中添加元素时,既可以添加E类型对象,又可以添加E的子类型对象。为什么因为取的时候,E类型既可以接收E类对象,又可以接收E的子类型对象。
6.2.下限:?super E:可以接收E类型或者E的父类型对象。
ArrayList<? extends Number > list = new ArrayList<String>();//错误,因为Number不是String的父类
下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接收,也可以用当前元的父类型接收。
7.1.swap(new String[3],3,4) -> static<T> void swap(T[] a, int i,int j);不用怀疑这是String泛型参数类型
7.2.add(3,5) -> static<T> T fill(T a,T b);不用怀疑这是int泛型参数类型
7.3.add(3,3.5f) -> static<T> T add(T a,T b);这种情况根据实参的交集来决定泛型参数类型(一个int,一个float,将个类型包装后为Intege 和Float,这两个类型的父类为Number), 因此泛型参数类型为Number,若有返回值得话返回值为Integer,否则编译不通过;
7.4.fill(new Integer[3],3.5f) -> static<T> void fill(T[] a,T b);第一个为Integer,第二个Float,交集为Integer。
7.5.copy(new Integer[5],new String[5]) -> static<T> void copy(T[] a,T[] b);根据交集泛型参数类型为
Integer copy(new Vector<String>(),new Integer[5]) -> static<T> void copy(Collection<T> a,T[] b);//由于泛型参数具传递性,因 此会有编译错
示例代码如下:用反射获取泛型参数类型
- [java] view plaincopyprint?
- <pre name="code" class="java">package com.JavaSE.GenericReflect;
-
- import java.lang.reflect.Method;
- //由于泛型参数类型变量不保存在字节码中,因此在获取类的字节码时拿不到泛型参数的类型,但是可以通过反射方法拿到
- //通过反射获得参数类型,根据范型参数类获得
- public class GenericReflectTest {
- public static void main(String[] args) throws Exception {
-
- /**
- * 1.通过反射获取类的字节码后在获取方法对象
- * 2.获取到反射方法的对象之后再获取形参类型,返回值为Type数组
- * 3.将Type类型转换为ParameterizedType类型
- * 4.再通过ParameterizedType对象的getRawType()方法获取形参类型和getActualTypeArguments()[0]方法泛型参数类型(泛型参数类型可能有多个,根据 角标获得)
- */
- Method method = GenericReflectTest.class.getMethod("applyVector1",new Class[]{Vector.class,List.class});
- Type[] types = method.getGenericParameterTypes();//获取到反射方法的对象之后再获取形参类型,根据顺序获取
- for(Type t : types){
- System.out.println(((ParameterizedType)t).getRawType());
- System.out.println(((ParameterizedType)t).getActualTypeArguments()[0]);
- }
- }
- public static void applyVector(Vector<Date> v1){
-
- }
- public static void applyVector1(Vector<String> v1,List<Integer> v2){
-
- }
-
- }
复制代码
|