泛型以及通配符

一:泛型

泛型类:class FanxingTest<T>{ }

泛型方法:public <T> T fanxingMethod(T...a){ // 泛型方法
                     return a[a.length/2];
                 }

示例:

public class GenericMethod3 {
    static class Fruit{
        @Override
        public String toString() {
            return "fruit";
        }
    }

    static class Apple extends Fruit{
        @Override
        public String toString() {
            return "apple";
        }
    }

    static class Person{
        @Override
        public String toString() {
            return "Person";
        }
    }

    static class GenerateTest<T>{ // 泛型类
        //普通方法
        public void show_1(T t){
            System.out.println(t.toString());
        }

        //在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。
        // 可以类型与T相同,也可以不同。
        //由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,
        // 编译器也能够正确识别泛型方法中识别的泛型。
        public <E> void show_3(E t){ // 泛型方法
            System.out.println(t.toString());
        }

        //在泛型类中声明了一个泛型方法,使用泛型T,
        // 注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。
        public <T> void show_2(T t){ // 泛型方法
            System.out.println(t.toString());
        }
    }

    public static void main(String[] args) {
        Apple apple = new Apple();
        Person person = new Person();

        GenerateTest<Fruit> generateTest = new GenerateTest<>();
        generateTest.show_1(apple);
        //generateTest.show_1(person); // 编译报错

        generateTest.show_2(apple);
        generateTest.show_2(person);

        generateTest.show_3(apple);
        generateTest.show_3(person);
    }
}

二 :通配符

限定上界:? extends XXX (规定了:只能传入的参数是XXX,或者XXX的子类,XXX的父类/或者以上的类不能传,上界)

限定下界:? super XXX (规定了:只能传入的参数是XXX, 或者XXX 的父类,XXX 的子类/或者以下的类不能传,下界)

示例:(Food-Fruit-Orange/Apple(Apple-HongFuShi))

public class WildChar{

    public static void print(GenericType<Fruit> p){ // print 只接受 GenericType<Fruit>参数,即是GenericType类型而且泛型是Fruit
        System.out.println(p.getData().getColor());
    }

    public static void use(){
       GenericType<Fruit> a = new GenericType<>();
        print(a); // a 对象是 GenericType类型,而且泛型是Fruit
       GenericType<Orange> b = new GenericType<>();
        //print(b); // 报错,因为 b的类型,虽然是GenericType,但是泛型是Orange, 不能调用print()方法
    }


    public static void print2(GenericType<? extends Fruit> p){ // 通配符? ,这里只能传入Fruit,及其子类,上界是Fruit, Fruit 上面的类Food是会报错的
        System.out.println(p.getData().getColor());
    }

    public static void use2(){
        GenericType<Fruit> a = new GenericType<>();
        print2(a);
        GenericType<Orange> b = new GenericType<>();
        print2(b);
        //print2(new GenericType<Food>()); // 报错,上界是Fruit,但是传入了Fruit 的父类Food 是不可以的


        GenericType<? extends Fruit> c =  new GenericType<>();

        Apple apple =  new Apple();
        Fruit fruit = new Fruit();
        //c.setData(apple); 
        //c.setData(fruit);
        Fruit x = c.getData();  // 因为c 获取到的一定是 Fruit 类或者Fruit的子类,所以可以去get
    }

    public static void printSuper(GenericType<? super Apple> p){
        System.out.println(p.getData());
    }

    public static void useSuper(){
        GenericType<Fruit> fruitGenericType = new GenericType<>();
        GenericType<Apple> appleGenericType = new GenericType<>();
        GenericType<HongFuShi> hongFuShiGenericType = new GenericType<>();
        GenericType<Orange> orangeGenericType = new GenericType<>();
        printSuper(fruitGenericType);
        printSuper(appleGenericType);
//        printSuper(hongFuShiGenericType); // 报错,下界是Apple, 只能传Aplle,或者Apple 的父类,printSuper方法的参数规定了下界
//        printSuper(orangeGenericType);


        //表示GenericType的类型参数的下界是Apple
        GenericType<? super Apple> x = new GenericType<>();
        x.setData(new Apple());
        x.setData(new HongFuShi());
        //x.setData(new Fruit());
        Object data = x.getData();

    }

}

三:泛型擦除

示例:

public class Restrict<T> {
    private T data;

    //不能实例化类型变量
//    public Restrict() {
//        this.data = new T();
//    }

    //静态域或者方法里不能引用类型变量
    //private static T instance;
    //静态方法 本身是泛型方法就行
    //private static <T> T getInstance(){}


    public static void main(String[] args) {
        //Restrict<double>
        Restrict<Double> restrict = new Restrict<>();
        Restrict<String> restrictString= new Restrict<>();

        System.out.println(restrict.getClass()==restrictString.getClass()); // true,因为两者打印出来都是Restrict
        System.out.println(restrict.getClass().getName()); // cn.enjoyedu.generic.Restrict
        System.out.println(restrictString.getClass().getName()); // cn.enjoyedu.generic.Restrict

        Restrict<Double>[] restrictArray;  // 带泛型的数组,声明可以,初始化不行
        //Restrict<Double>[] restricts = new Restrict<Double>[10];  // 带泛型的数组,声明可以,初始化不行
        //ArrayList<String>[] list1 = new ArrayList<String>[10];  // 带泛型的数组,声明可以,初始化不行
        //ArrayList<String>[] list2 = new ArrayList[10];  // 带泛型的数组,声明可以,初始化不行
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值