Hello范型

为什么需要范型?

1.适用于多种数据类型,执行相同的代码。

2.使用范型后,在编码的时候可以直接指定数据类型,插入错误的数据类型,在编译期间直接不通过。

范型类

public class NormalGeneric<T> {
    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public NormalGeneric(T data) {
        this.data = data;
    }

    public NormalGeneric() {
    }

    public static void main(String[] args) {
        NormalGeneric<String> normalGeneric=new NormalGeneric<>();
        normalGeneric.setData("hello");
        NormalGeneric<Integer> normalGeneric1=new NormalGeneric<>(1);
    }
}

范型接口

public interface IGeneric<T> {
     T next();
}

public class ImplGeneric<T> implements IGeneric<T> {
    @Override
    public T next() {
        return null;
    }
}

public class Impl2Generic implements IGeneric<String> {
    @Override
    public String next() {
        return null;
    }
}

范型方法

public class GenericMethod {

    public <T> T print(T... a) {
        return a[a.length / 2];
    }

    public static void main(String[] args) {
        GenericMethod genericMethod=new GenericMethod();
        genericMethod.print("a","b");
    }
}

类型变量的限定-方法上

public static <T extends Comparable> T min(T a, T b) {
        if (a.compareTo(b) > 0) {
            return a;
        } else {
            return b;
        }
    }
  
//单继承多实现

public static <T extends ArrayList & Comparable & Runnable> T min2(T a, T b) {
        if (a.compareTo(b) > 0) {
            return a;
        } else {
            return b;
        }
    }

范型的局限性

public class NormalGeneric<T> {
    private T data;

    public NormalGeneric(){
        //此处会发生错误,不能实例化类型变量
        this.data=new T();
    }
    //此处会发生错误,静态域或者方法里不能引用类型变量
    //虚拟机在创建对象时,先执行的静态后执行的构造
    private static T instance;
    public static  void get(T t){}
    //正常编译,静态方法本身就是范方法
    public static <T> void print(T t){}
}


public class Restrict<T> {
    private T data;

    public static void main(String[] args) {
        Restrict<Double> d1 = new Restrict<>();
        Restrict<Double> d2 = new Restrict<>();
        //泛型不允许用instanceof
        //if(d1 instanceof Restrict<Double>){
        //}
        //可以这样使用
        if (d1 instanceof Restrict) {
            System.out.println(">>>>>");
        }
        //false
        System.out.println(d1 == d2);
        //true
        System.out.println(d1.getClass() == d2.getClass());
        //com.hello.android.Restrict
        System.out.println(d2.getClass());

        Restrict<Double>[] d1Array;
        //编译异常
        //Restrict<Double>[] d2Array=new Restrict<Double>[10];
        //编译正常
        Restrict<Double>[] d3Array = new Restrict[10];
        d3Array[0] = d1;
        d3Array[1] = d2;
        System.out.println(d3Array);

        //泛型类不能extends Exception\Throwable
    }

    //不能捕获泛型类对象
//    public <T extends Throwable> void test(T t) {
//        try {
//
//        } catch (T t2) {
//
//        }
//    }

    //这样允许捕获泛型类对象
    public <T extends Throwable> void test2(T t) throws T {
        try {

        } catch (Throwable x) {
            throw t;
        }
    }
}

范型类的继承规则

package com.hello.android;

public class Pair<T> {
    private T one;
    private T two;

    public static void main(String[] args) {
        //Employee与 Worker存在继承关系,但employeePair完全与workerPair不存在继承关系
        Pair<Employee> employeePair = new Pair<>();
        Pair<Worker> workerPair = new Pair<>();

        //泛型类是可以继承
        Pair<Employee> employeePair1 = new ExtPair<>();

    }


    public static class ExtPair<T> extends Pair<T> {

    }
}

通配符

package com.hello.android;

public class Pair<T> {
    private T one;
    private T two;

    public void setOne(T one) {
        this.one = one;
    }


    public static void main(String[] args) {
        //Worker extends Employee存在继承关系,但employeePair完全与workerPair不存在继承关系
        Pair<Employee> employeePair = new Pair<>();
        Pair<Worker> workerPair = new Pair<>();

        //正常编译
        set(employeePair);
        //编译出错
        //set(workerPair);

        //正常编译
        set2(employeePair);
        //采用通配符方式正常编译
        set2(workerPair);

        //正常编译
        set3(employeePair);
        //正常编译,super代表的下边界不能低于Worker
        set3(workerPair);

        //Worker extends Employee、 Employee extends Skill存在继承关系,
        //与在方法里使用的通配符理解不一样
        //此处理解为Employee和Employee的子类可以set操作,可以安全的进行类型转型,而Skill不行
        Pair<? super Employee> pair = new Pair<>();
        pair.setOne(new Worker());
        pair.setOne(new Employee());
        //编译出错
        //pair.setOne(new Skill());

    }

    public static void set(Pair<Employee> e) {

    }

    //通配符用在方法上 extends代表上边界不能超过Employee,Employee、Employee的子类
    public static void set2(Pair<? extends Employee> e) {

    }

    //通配符用在方法上 super代表下边界不能低于Worker,Worker、Worker的基类
    public static void set3(Pair<? super Worker> e) {

    }

}

虚拟机如何实现泛型

类型擦除

    //编译器不通过,方法重载,但编译器对泛型进行类型擦除后,属于同一个类型,导致编译不通过
    public static void method(List<String> params){

    }

    public static void method(List<Integer> params){

    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值