泛型复习

回顾泛型类

泛型类:具有一个或多个泛型变量的类被称之为泛型类
1、class A<T>{
}

2、在创建泛型实例时,需要为其类型变量赋值
A<String> a=new A<String>();
*如果创建实例时,不给类型变量赋值,那么会有一个警告!

3、泛型方法:具有一个或多个类型变量的方法,称之为泛型方法!
class A<T>{
public T fun(T t1){}
}
fun()方法不是泛型方法!它是泛型类中的一个方法!
public <T> T fun(T t1){} -->它是泛型方法
*泛型方法和泛型类没有什么关系,泛型方法不一定非要在泛型类中!

4、泛型在类中或者方法中的使用
*泛型类中使用泛型:
>成员类型
>返回值类型和参数类型
>局部变量的引用上
class A<T>{
private T bean;//泛型可在成员变量上使用
public T fun(T t){}//泛型可以在类中的方法上(返回值和参数类型)使用!

public void fun2(){//泛型还可以在局部变量的引用类型上使用
T b=...
new T();//不行的
}
}

=====================================
5、泛型的继承和实现
class A<T>{}
class AA extends A<String>{} //不是泛型类,只是它爸爸是泛型类!

5.1 继承泛型类
*子类不是泛型类:需要给父类传递类型常量
>当给父类性传递的类型常量为String时,那么在父类中所有T都会被String替换
*子类是泛型类:可以给父类传递类型常量,也可以传递泛型变量

class AA1 extends A<Integer>{}
class AA3<E1> extends A<E1>(){}

============================================
泛型的通配符
1、通配符的使用场景
方法的形参!
2、通配符的优点
使方法更加通用!

3、通配符分类
无界通配 ?
子类限定:? extends Object
父类限定:? super Integer

4、通配符缺点
使变量使用上不再方便
无界:参数和返回值为泛型的方法不能使用
子类:参数为泛型的方法不能使用
父类:返回值为泛型的方法不能使用

5、比较通配符
boolean addAll(Collection<E> c)

List<Number> numList=new ArrayList<Number>();
List<Integer> intList=new ArrayList<Integer>();
numList.add(intList);//编译失败

boolean addAll(Collection<? extends E> c)

List<Number> numList=new ArrayList<Number>();
List<Integer> intList=new ArrayList<Integer>();
numList.add(intList);

 

package cn.itcast;

import org.junit.Test;

public class Demo1 {
    @Test
    public void fun1(){
        AA3<Long> aa3=new AA3<Long>();
        
    }
}
class A<T>{
    private T t;
    
    public T fun1(){
        return t;
    }
    
    public void fun2(T t){
        this.t=t;
    }
    
}

class AA1 extends A<Integer>{
    
}
class AA2 extends A<String>{
    
}

class AA3<E> extends A<E>(){
}


package cn.itcast;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class Demo2 {
    
    @Test
    public void fun1(){
        Object[] objs=new Object[10];
        List list=new ArrayList();
        
        String[] strs=new String[10];
        List<String> strList=new ArrayList<String>();
        
        Object[] objArray=new String[10];
        objArray[0]=new Integer(100);//java.lang.ArrayStoreException: java.lang.Integer

//        List<Object> objList=new ArrayList<String>();
        /*
         * 泛型引用和创建两端,给出的泛型变量必须相同!
         */
        
    }
    
    public void fun2(){
        List<Integer> integerList=new ArrayList<Integer>();
        print(integerList);//List<Object> list=new ArrayList<Integer>(); 
        
        List<String> strList=new ArrayList<String>();
        print(strList);
    }
    /*
     * 这个?就是通配符
     * 通配符只能出现在左边!,即不能再new时使用通配符!!!
     * List<? extends Object> list=new ArrayList<String>();
     */
    /*
     * ?它表示一个不确定的类型,它的值会在调用时调用下来
     */
    public void print(List<?> list){
        /*
         * 当使用通配符,对泛型类中参数为泛型的方法起到了副作用
         */
        //list.add("hello");
        /*
         * 当使用通配符时,泛型类中返回值为泛型的方法也作废了
         */
        Object s=list.get(0);
        /*
         * 通配符的好处:可以使泛型类型更加通用!尤其是在方法调用时形参使用通配符
         */
        
    }
    
    public void fun3(){
        List<Integer> intList=new ArrayList<Integer>();
        print1(intList);
        
        List<Long> lonList=new ArrayList<Long>();
        print1(lonList);
        
//        List<String> strList=new ArrayList<String>();
//        print1(strList);
    }
    
    /*
     * 给通配符添加了限定
     *     只能传递Number或其子类
     *     子类统配对通用性产生了影响,但使用形参更加灵活
     */
    public void print1(List<? extends Number> list){
        /*
         * 参数为泛型的方法还是不能使用
         */
//        list.add(new Integer(100));
        /*
         * 返回值为泛型的方法可用
         */
        Number number=list.get(0);
    }
    
    public void fun4(){
        List<Integer> intList=new ArrayList<Integer>();
        print2(intList);
        
//        List<Long> lonList=new ArrayList<Long>();
//        print2(lonList);
        
        List<Object> objList=new ArrayList<Object>();
        print2(objList);
        
    }
    
    /*
     * 给通配符添加了限定
     * 只能传递Integer类型,或其父类型
     */
    public void print2(List<? super Integer> list){
        /*
         * 参数为泛型的方法可以使用了
         */
        list.add(new Integer(100));
//        Integer int1=list.get(0);
        /*
         * 返回值为泛型的方法,还是不能使用
         */
        Object obj=list.get(0);
        
    }
    
}

 

反射获取类上面的泛型信息:

package cn.itcast.demo1;

import java.lang.reflect.ParameterizedType;

import org.junit.Test;

public class Demo1 {
    @Test
    public void fun1(){
        new C();
    }
    
}

class A<T>{
    public A(){
        /*
         * 在这里获取子类传递的泛型信息
         */
//        Type type=this.getClass().getGenericSuperclass();//获取父类的参数化类型 格式为A<String>或。。。
//        ParameterizedType pType=(ParameterizedType) type;
//        Class c=(Class) pType.getActualTypeArguments()[0];//参数的Class数组
        Class c=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        System.out.println(c.getName());
    }
}
class B extends A<Integer>{
    
}
class C extends A<String>{
    
}
View Code

 

posted @ 2016-08-18 21:23  guodaxia  阅读(168)  评论(0编辑  收藏  举报