泛型

作者: 飞马_6886 | 来源:发表于2019-06-29 16:28 被阅读0次

    泛型使用的地方:分3种

    泛型类
    public class Generic<T> {
        private T dtaa;
    
        public Generic() {
        }
    
        public Generic(T dtaa) {
            this.dtaa = dtaa;
        }
    
        public T getDtaa() {
            return dtaa;
        }
    
        public void setDtaa(T dtaa) {
            this.dtaa = dtaa;
        }
    
        public static void main(String[] args) {
            Generic<String> generic = new Generic();
            generic.setDtaa("NICE");
            System.out.println(generic.getDtaa());
        }
    
    }
    
    泛型接口
    public interface IGeneric<T> {
        T next();
    }
    
    public class ImplGeneric<T> implements IGeneric<T> {
        @Override
        public T next() {
            return null;
        }
    }
    
    public class ImplGeneric2<T> implements IGeneric<String>{
    
        @Override
        public String next() {
            return null;
        }
    }
    
    泛型方法
      public class GenericMethod {
    
        public <T> T generMethod(T ... a){
            return  a[a.length/2];
        }
    
        public static void main(String[] args) {
            GenericMethod method = new GenericMethod();
    
            System.out.println(method.generMethod("lili","HanMei","LiuLiu","MM"));
            System.out.println(method.generMethod(11,22,12,33));
        }
    }
    
    

    运行结果:
    LiuLiu
    12

    钻石运算符:<>

    JDK7以前 必须写全
    JDK8 可以省略

    单一限制 <T extends A>
    多重限制 <T extends A & B & C>
    后面不能有多个类 可以有多个接口

    类型推断:取两个或多个参数的交集(相同的类型或接口)

    List<?> list ----- 退化
    Java 伪泛型 (虚拟机或编译后就是具体类型了) 为了兼容低版本(JDK5)
    类型擦拭

    泛型在使用时的限制和约束:

    1.不能实例化类型变量
    如 new T();
    2.静态域或方法不能引用类型变量
    如: public static T instance; (不允许 编译报错)
    3.不能用基本类型,如 int, double。要用 Integer Double
    4.不能用Instance of
    5.不能extends Exception
    6.不能捕获泛型类的异常 :catch 的时候。但是可以直接抛异常 :Throw

    泛型的异常捕获
    注意事项:

    1,getClass == getClass 与传入的泛型类型无关
    2,声明可以,实例化 new 不可以。
    3.子类和父类作为泛型时,不再有继承关系。

    通配符 <? extends Fruit>

    1.定义类时不能用 在方法中可以使用
    2.extends时有界限 只往下 不能向上 传参时 apple orange 可以 父类Food不行
    3.可以访问数据 set不行

    <? super Apple>

    1.传参时 父类及本身可以 子类不可以
    2.set时 子类及本身可以(可以安全转型) 父类不行

    编译器擦除

    <? extends Comparable&ArrayList&>
    编译器会默认 转成第一个Comparable
    当有用到后面泛型的方法时 ,会转成对应的类型。

    下面,举个栗子更容易理解通配符:

    其中有几个类的继承关系如下:
    A :父类
    A1,A2:是A的子类
    B:是A1的子类
    B1:是B的子类
    C:是B1的子类

    public class Demo<T> {
        //PECS 原则(Producer Extends Consumer Super)
        //只读
        public void testExtends(List<? extends T> list){
            System.out.println("testExtends....");
        }
        //只写
        public void testSuper(List<? super T> list){
            System.out.println("testSuper.....");
        }
        public static void main(String[] args) {
            Demo<B> bDemo = new Demo<>();
    
            List<A> aList = new ArrayList<>();
            List<A1> a1List = new ArrayList<>();
            List<A2> a2List = new ArrayList<>();
            List<B> bList = new ArrayList<>();
            List<B1> b1List = new ArrayList<>();
            List<C> cList = new ArrayList<>();
    
            bDemo.testExtends(aList); //会报错
            bDemo.testExtends(a1List); //会报错
            bDemo.testExtends(a2List); //会报错
            bDemo.testExtends(bList);
            bDemo.testExtends(b1List);
            bDemo.testExtends(cList);
    
            bDemo.testSuper(aList);
            bDemo.testSuper(a1List);
            bDemo.testSuper(a2List); //会报错
            bDemo.testSuper(bList);
            bDemo.testSuper(b1List);//会报错
            bDemo.testSuper(cList); //会报错
        }
    

    下图可以通过图片直观的看出编译器报错:


    泛型访问限制.png

    相关文章

      网友评论

          本文标题:泛型

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