美文网首页
带你搞懂Java泛型

带你搞懂Java泛型

作者: 爺珍爱那颗心 | 来源:发表于2019-12-29 22:59 被阅读0次

    什么是泛型

    参数化的类型:将需要传入的属性,进行参数化,实际调用时才指定传入的数据类型。

    为什么要用泛型

    • 同样的一段代码逻辑相同,只是传入的参数不同,如果不使用泛型就需要进行很多方法的重写
    • 运行时产生类型转换异常。
      如List list = new ArrayList();
      list.add("a");
      list.add(1);
      取的时候需要强制类型转换,会产生错误。

    使用泛型的好处

    • 实现传入不同的参数,来执行相同的代码。
    • 严格要求传入的参数类型,不需要强制类型转换,编译期间就可以发现错误。

    泛型种类

    • 泛型类

    定义泛型类:只需在类名后面加尖括号即可,尖括号中的字母可随意设置

    public class Demo<T>{
     private T data;
     public T getData(){
           return data;
       }
     public void setData(T data){
       this.data = data;
    }
    }
    public static void main(String[]args){
     Demo<String>demo = new Demo<>();
     demo.setData("test");
     
    }
    
    • 泛型方法

    定义泛型方法:修饰符返回值类型中间要有<参数类型>,泛型方法可定义在任意位置。
    注意 定义在泛型类中的泛型方法,传入的参数类型可以与泛型类传入的类型不同,泛型类传入的类型只影响普通方法。

    public <T> T demo(T t){
      return t;
    }
    调用的两种方式:
    1.<String>demo("a");
    2.demo("a");
    
    
    • 泛型接口

    定义泛型接口:与泛型类类似只需在方法名后面加尖括号即可,尖括号中的字母可随意设置

    public interface Demo<T>{
      public T demo();
    }
    

    泛型接口的两种实现方式:
    第一种

    public class ImpDemo<T>implements Demo<T>{
      @Override 
      public T demo(){
        return null;
      }
    }
    

    第二种

    public class ImpDemo<T>implements Demo<String>{
      @Override
      public String demo(){
        return null;
      }
    }
    

    类型变量的限定

    注意T extends 可继承一个类和多个接口通过&来间隔,但只能继承一个类,并且需写在第一个。
    因为java语法规定单继承多实现且必须类放在第一个。
    泛型类和方法通用。

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

    泛型的缺点

    • 约束和局限性
      ①不能实例化类型变量
      ②静态域或方法里不能引用类型变量因为static关键字是在实例化之前进行处理的,所以编译器不能确定要生成何种类型
      静态方法本身是泛型方法可以
    public class Demo<T>{
      private T data;
      public Demo{
    //①
        this.data = new T();
      }
    
    }
    

    ③泛型不支持基本数据类型但支持他们的包装类因为泛型需要对象类型
    ④不支持类型判定即不支持instanceof,因为编译时会对泛型进行擦除。
    ⑤可以定义泛型数组,但不能创建泛型数组。
    ⑥泛型类不能继承异常e xtend Exception,也不能捕获泛型异常
    有一种写法可以

    public <T extend Throwable> void doSomeThing(T t) throws T{
      try{}catch(Throwable e){
        throw t;
      }
    }
    

    类型的继承规则

    泛型没有任何继承关系但泛型类可以继承或扩展其他泛型类,如List和ArrayList

    通配符类型

    • 用来解决泛型没有任何继承关系的问题
      ①定义通配符:<? extend 类>
      ?代表子类类本身
      注意只能使用在方法上不能在类上用,且类代表了上界,即?不能传入类的父类
      不支持set且只能get上界本身
      用于安全的访问数据
      ②定义通配符:<? super 类>
      ?代表类的父类
      注意只能使用在方法上不能在类上用,且类代表了下界,即?不能传入类的子类
      支持set类本身和类的子类,不能set类的父类
      用于安全的写入数据

    虚拟机是如何实现泛型

    类型擦除,变成了Object,如果泛型有extends 则取extends的第一个用来作为擦除类型,伪泛型jdk编译时会自动做类型转换。

    到这了泛型就全部记录在这里了,如果你觉得对你有帮助,可以点赞关注,这个系列会持续进行更新的。

    最后送一句话给自己也与各位共勉

    行百里者半九十,不要轻易自满,永远记得坚持超越自己,加油!!!

    相关文章

      网友评论

          本文标题:带你搞懂Java泛型

          本文链接:https://www.haomeiwen.com/subject/bhhuoctx.html