• 2.Java泛型指南-泛型擦除、泛型表达式、类型边界、通配符、无限制通配符、上界通配符下界通配符、泛型作用域、类型上限、?类型泛型、构造函数泛型,泛型使用规则


    泛型的规则

    类型擦除

    类擦除案例
    jdk1.5之前代码
    public class Node{
       private Object obj;
    
       public Object get(){
           return obj;
       }
       
       public void set(Object obj){
           this.obj=obj;
       }
       
       public static void main(String[] argv){
        
        Student stu=new Student();
        Node  node=new Node();
        node.set(stu);
        Student stu2=(Student)node.get();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    使用泛型的代码
    public class Node<T>{
    
        private T obj;
        
        public T get(){
            
            return obj;
        }
        
        public void set(T obj){
            this.obj=obj;
        }
        
        public static void main(String[] argv){
        
        Student stu=new Student();
        Node<Student>  node=new Node<>();
        node.set(stu);
        Student stu2=node.get();
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    两个版本生成的.class文件
      public Node();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."":()V
           4: return
      public java.lang.Object get();
        Code:
           0: aload_0
           1: getfield      #2                  // Field obj:Ljava/lang/Object;
           4: areturn
      public void set(java.lang.Object);
        Code:
           0: aload_0
           1: aload_1
           2: putfield      #2                  // Field obj:Ljava/lang/Object;
           5: return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    public class Node<T> {
      public Node();
        Code:
           0: aload_0
           1: invokespecial #1                  // Method java/lang/Object."":()V
           4: return
      public T get();
        Code:
           0: aload_0
           1: getfield      #2                  // Field obj:Ljava/lang/Object;
           4: areturn
    
      public void set(T);
        Code:
           0: aload_0
           1: aload_1
           2: putfield      #2                  // Field obj:Ljava/lang/Object;
           5: return
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    可以看到泛型就是在使用泛型代码的时候,将类型信息传递给具体的泛型代码。而经过编译后,生成的.class文件和原始的代码一模一样,就好像传递过来的类型信息又被擦除了一样。

    方法擦除案例
    public class ArrayAlg {
    
        public static <T> T getMiddle(T... a) {
            return a[a.length / 2];
        }
    
        //编译后的实际代码,演示方法擦除
        public static Object getMiddle(Object ... a) {
            return a[a.length / 2];
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    编译器桥接
    package com.naixue.vip.p6.bridging;
    
    /**
     * @Description
     * @Author xh 
     * @Date 2020/7/7 11:05
     **/
    public class Node<T> {
        public T data;
    
        public void setData(T data) {
            this.data = data;
        }
    
        public Node(T data) {
            System.out.println("Node.setData");
            this.data = data;
        }
        public static class MyNode extends Node<Integer>{
    
            public MyNode(Integer data) {
                super(data);
            }
    
            @Override
            public void setData(Integer data) {
                System.out.println("MyNode.setData");
                super.setData(data);
            }
    
            //模拟编译器产生的桥接方法
    //        public void setData(Object data){
    //            setData((Integer)data);
    //        }
        }
        public static void main(String[] args) {
            MyNode mn=new MyNode(5);
            Node n=mn;
            //java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
            n.setData("Hello");
            Integer x=mn.data;
            System.out.println(x);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    堆污染

    Heap pollution(堆污染), 指的是当把一个不带泛型的对象赋值给一个带泛型的变量时, 就有可能发生堆污染.

    package com.naixue.vip.p6.heappollution;
    
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description 堆污染案例
     * Heap pollution(堆污染), 指的是当把一个不带泛型的对象赋值给一个带泛型的变量时, 就有可能发生堆污染.
     * @Author xh 
     * @Date 2020/7/7 11:24
     **/
    public class Pollution {
    
        public void funa() {
            List intList = new ArrayList<Integer>();
            intList.add(1);
            //堆污染:类型转换异常
    //        List strList = intlist;
        }
    
        @Test
        public void funb() {
            List<Integer> intList = new ArrayList<>();
            intList.add(1);
    
            List<String> strList = new ArrayList<>();
            strList.add("a");
    
            //通过泛型做到了转换,编译通过
            List list=intList;
            List<String> lst=list;
    
            //运行时会发生转换异常
            //java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
            System.out.println(lst.get(0));
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    翻译泛型表达式

    Pair<Parson> pair=new Pair<Parson>();
    pair.getFirst();
    
    • 1
    • 2

    擦除getFirst的返回类型后将返回Object类型。编译器自动插入Employee的强制类型转换

    编译器把这个方法调用翻译为两条虚拟机指令:

    • 对原始方法Pair.getFirst的调用。
    • 将返回的Object类型强制转换为Parson类型。

    子类型规则

    类型边界

    泛型T在最终会擦除为Object类型,只能使用Object的方法

    通配符

    假设有一种场景,你不知道这个类型是啥,它可以是Object,也可以是其他类那咋办?

    这种场景就需要用到通配符

    <T extends Parson>
    <T super Parson>
    <?>
    <? extends Parson>
    <? super Parson>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    无限制通配符

    使用原生态类型是很危险的,但是如果不确定或不关心实际的类型参数。那么在Java 1.5之后Java有一种安全的替换方法,称之为无限制的通配符类型(unbounded wildcard type),可以用一个“?”代替,比如Set表示某个类型的集合,可以持有任何集合。

    那么无限制通配类型与原生态类型有啥区别呢?原生态类型是可以插入任何类型的元素,但是无限制通配类型的话,不能添加任何元素(null除外)。

    Set set=new HashSet<>();
    set.add("abc");//编译错误
    
    • 1
    • 2

    它的出现归根结底是为了防止破坏集合类型约束条件,并且可以根据需要使用泛型方法或者有限制的通配符类型(bound wildcard type)接口某些限制,提高安全性。

    上界通配符

    可以扩展为父类,来调用其方法。必须是子类或者本身。

    父类Parson
    package com.naixue.vip.p6.vo;
    
    /**
     * @Description 人的class
     * @Author xh 
     * @Date 2020/7/6 17:03
     **/
    public class Parson {
    
        private String name;
    
        private Integer age;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Parson() {
        }
    
        public Parson(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        @Override
        public String toString() {
            return name+","+age;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    子类Man
    package com.naixue.vip.p6.vo;
    
    /**
     * @Description 男人的class
     * @Author xh 
     * @Date 2020/7/6 17:03
     **/
    public class Man extends Parson{
    
        private String watch;
    
        private String car;
    
        public Man(String name, Integer age, String watch, String car) {
            super(name, age);
            this.watch = watch;
            this.car = car;
        }
    
        @Override
        public String toString() {
            return super.getName() + "," + super.getAge()+","+watch+","+car;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    子类Woman
    package com.naixue.vip.p6.vo;
    
    /**
     * @Description 女人的class
     * @Author xh 
     * @Date 2020/7/6 17:03
     **/
    public class Woman extends Parson {
    
        private String bag;
    
        private String lipstick;
    
        public Woman() {
    
        }
    
        public Woman(String name, Integer age, String bag, String lipstick) {
            super(name, age);
            this.bag = bag;
            this.lipstick = lipstick;
        }
    
        @Override
        public String toString() {
            return super.getName() + "," + super.getAge()
                   + "," + bag + "," + lipstick;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    上界通配符和类型限定
    package com.naixue.vip.p6.wildcard;
    
    import com.naixue.vip.p6.classes.Pair;
    import com.naixue.vip.p6.vo.Man;
    import com.naixue.vip.p6.vo.Parson;
    import com.naixue.vip.p6.vo.Woman;
    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    /**
     * @Description 泛型类型限定,只能使用子类
     * @Author xh 
     * @Date 2020/7/6 19:56
     **/
    public class Programmer<T extends Parson> {
    
        public <T extends Parson> Pair<T> youngAndOld(T[] a) {
            if(a == null || a.length == 0) {
                return null;
            }
            T min = a[0];
            T max = a[1];
            for(int i = 0; i < a.length; i++) {
                if(min.getAge().compareTo(a[i].getAge()) > 0) {
                    min = a[i];
                }
                if(max.getAge().compareTo(a[i].getAge()) < 0) {
                    max = a[i];
                }
            }
            return new Pair<>(min, max);
        }
    
        public void count(Collection<Parson> persons) {
            System.out.println(persons.size());
        }
    
        @Test
        public void countTest() {
            List<Man> manList=new ArrayList<>();
            //违反子类型化原则,编译报错
    //        new Programmer().count(manlist);
        }
    
        public static void main(String[] args) {
            Programmer<Parson> programmer = new Programmer<Parson>();
            Man man=new Man("陈先生",48,"劳力士","幻影");
            Woman woman=new Woman("刘女士",27,"LV","迪奥");
            Man man1=new Man("张先生",32,"浪琴","奥迪");
            Woman woman1=new Woman("吴女士",18,"LV","圣罗兰");
            Parson[] parsons=new Parson[4];
            parsons[0]=man;
            parsons[1]=woman;
            parsons[2]=man1;
            parsons[3]=woman1;
    
            //符合上界通配符规则
            Pair<Parson> parsonPair = programmer.youngAndOld(parsons);
    
            //子类型规则,即任何参数化的类型是原生态类型的一个子类型,
            //Programmer是Programmer类型的一个子类型,而不是Programmer的子类型。
    //        Programmer programmer1 = new Programmer();
    //        Programmer programmer1 = new Programmer();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    多限定
    public class Programmer<T extends Parson & Serializable> {
    		
    }
    
    • 1
    • 2
    • 3
    下界通配符
        public <T> void func(List<? super Man> src) {
            
        }
    
        @Test
        public void testCopy() {
            Guide programmer = new Guide();
            programmer.func(new ArrayList<Man>());
            programmer.func(new ArrayList<Parson>());
            //违反下界通配符原则,编译不通过
    //        programmer.func(new ArrayList());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    泛型的作用域

    package com.naixue.vip.p6.wildcard;
    
    import com.naixue.vip.p6.vo.Man;
    import com.naixue.vip.p6.vo.Parson;
    import com.naixue.vip.p6.vo.Woman;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description 泛型的作用域 
     * @Author xh 
     * @Date 2020/7/6 20:54
     **/
    public class Guide<T> {
        /**
         * Hardworkinger的T的作用域是整个class,func的T的作用域就是本方法
         * 当上述两个类型参数冲突时,在方法中,方法的T会覆盖类的T,即和普通变量的作用域一样,内部覆盖外部,外部的同名变量是不可见的
         * @param t
         * @param 
         */
        public <T> void func(T t) {
    
        }
    
        /**
         * 可以定义不同类型泛型来区分作用域
         * @param s
         * @param 
         */
        public <S> void fund(S s) {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    类型上限

    package com.naixue.vip.p6.wildcard;
    
    import com.naixue.vip.p6.vo.Man;
    import com.naixue.vip.p6.vo.Parson;
    import com.naixue.vip.p6.vo.Woman;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description 泛型的类型上限
     * @Author xh 
     * @Date 2020/7/6 20:54
     **/
    public class Guide<T> {
        /**
         * 指定泛型方法的类型参数的上限
         * @param src
         * @param 
         * @return
         */
        public <T extends Parson> T funa(List<T> src) {
            return null;
        }
    
        /**
         * 不能在方法参数中定义上限
         * @param src
         * @param 
         */
    //    public  T funb(List src) {
    //        return null;
    //    }
    
        public <T> void copy(List<T> dest,List<? extends T> src) {
            for (T t : src) {
                dest.add(t);
            }
        }
    
        /**
         * 使用?还可以强制避免你对src做不必要的修改,增加的安全性
         * @param src
         * @param 
         */
        public <Parson> void updateError(List<? extends Parson> src) {
            for (Parson parson : src) {
                //No candidates found for method call t.setAge(1).
    //            parson.setage(1);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    正确使用?的类型

    ?表示不可修改的类型

    package com.naixue.vip.p6.wildcard;
    
    import com.naixue.vip.p6.vo.Man;
    import com.naixue.vip.p6.vo.Parson;
    import com.naixue.vip.p6.vo.Woman;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description 泛型的作用域 and 类型上限 and 使用?的不可修改类型
     * @Author xh 
     * @Date 2020/7/6 20:54
     **/
    public class Guide<T> {
    
        public <T> void copy(List<T> dest,List<? extends T> src) {
            for (T t : src) {
                dest.add(t);
            }
        }
    
        /**
         * 使用?还可以强制避免你对src做不必要的修改,增加的安全性
         * @param src
         * @param 
         */
        public <Parson> void updateError(List<? extends Parson> src) {
            for (Parson parson : src) {
                //No candidates found for method call t.setAge(1).
    //            parson.setage(1);
            }
        }
    
        public static void main(String[] args) {
            Guide<Parson> programmer = new Guide<Parson>();
            Man man=new Man("陈先生",48,"劳力士","幻影");
            Woman woman=new Woman("刘女士",27,"LV","迪奥");
            Man man1=new Man("张先生",32,"浪琴","奥迪");
            Woman woman1=new Woman("吴女士",18,"LV","圣罗兰");
            List<Parson> parsons=new ArrayList<Parson>();
            parsons.add(man);
            parsons.add(woman);
            parsons.add(man1);
            parsons.add(woman1);
    
            List<Parson> dest=new ArrayList<Parson>();
    
    
            programmer.copy(dest,parsons);
            for (Parson parson : dest) {
                System.out.println(parson);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    构造函数使用泛型

    package com.naixue.vip.p6.kv;
    
    /**
     * @Description 构造函数的通用方法使用
     * @Author xh 
     * @Date 2020/7/6 16:51
     **/
    public class GenericKV<K,V> {
        private K key;
        private V value;
    
        /**
         * 构造函数中使用泛型
         * @param key
         * @param value
         */
        public GenericKV(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey() {
            return key;
        }
    
        public void setKey(K key) {
            this.key = key;
        }
    
        public V getValue() {
            return value;
        }
    
        public void setValue(V value) {
            this.value = value;
        }
    
        /**
         * 静态方法中使用泛型
         * @param p1
         * @param p2
         * @param 
         * @param 
         * @return
         */
        public static <K,V> boolean compare(GenericKV<K,V> p1,GenericKV<K,V> p2){
            return p1.getKey().equals(p2.getKey()) && p1.getValue().equals(p2.getValue());
        }
    
        public static void main(String[] args) {
            GenericKV<Integer,String> a=new GenericKV<Integer,String>(1, "a");
            GenericKV<Integer,String> b=new GenericKV<Integer,String>(2, "b");
            System.out.println(compare(a, b));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    使用规范

    add时只能向下转型;向上转型要强转;
    具有上界的通配符泛型只能get,不能add除null外的对象;
    具有下界的通配符泛型可以add,但get获取对象为object类型;
    
    package com.nx.qiuping.vip.generic.wildcard;
    
    import com.nx.qiuping.vip.generic.vo.Jason;
    import com.nx.qiuping.vip.generic.vo.Man;
    import com.nx.qiuping.vip.generic.vo.Person;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @Description 泛型上限定通配符和下限定通配符案例
     * @Author xh 
     * @Date 2020/7/11 18:38
     **/
    public class Limited {
        public static  <T> void funa(List<? extends Man> src) {
    
        }
    
        public static  <T> void funb(List<? super Man> src) {
    
        }
    
        public static  <T> Integer func(List<? super Man> src) {
            return src.size();
        }
    
        public void test() {
            Limited.funa(new ArrayList<Man>());
            //上界通配符
            //限定参数只能是Man的子类和本身
    //        Limited.funa(new ArrayList());
    //        Limited.funa(new ArrayList());
    
            //下界通配符
            //限定参数只能是Man的父类和本身
            Limited.funb(new ArrayList<Man>());
            Limited.funb(new ArrayList<Person>());
    //        Limited.funb(new ArrayList());
    
            /**
             * 上界的list只能get,不能add(确切地说不能add出除null之外的对象,包括Object)。
             * 下界的list只能add,不能get。
             */
            List<? extends Person> flistTop = new ArrayList<Person>();
            flistTop.add(null);
            //上界add 对象会报错
            //add无法确定add是哪个子类,所以不允许add
    //        flistTop.add(new Man());
    //        flistTop.add(new Woman());
    //        flistTop.add(new Person());
    
            //子类直接可以赋值给父类,所以可以get
            Person fruit2 =new Man();
            Person fruit1 = flistTop.get(0);
    
            //下界
            List<? super Man> flistBottem = new ArrayList<Man>();
            flistBottem.add(new Man());
            flistBottem.add(new Jason());
            //因为父类不能直接赋值给子类所以不能add
    //        Man man=new Person();
    //        flistBottem.add(new Woman());
    
            //get的对象是? super Man 类型,模糊类型的所以不能直接复制给Man
    //        Man man3=flistBottem.get(0);
            //强转就可以了
            Man man4=(Man) flistBottem.get(0);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    Java泛型转换的事实

    • 虚拟机中没有泛型,只有普通的类和方法。
    • 所有的类型参数都用它们的限定类型替换。
    • 桥方法被合成来保持多态。
    • 为保持类型安全性,必要时插入强制类型转换。

    jdk定义了7种泛型的使用限制

    • 不能用简单类型来实例化泛型实例
    • 不能直接创建类型参数实例
    • 不能申明静态属性为泛型的类型参数
    • 不能对参数化类型使用cast或instanceof
    • 不能创建数组泛型
    • 不能create、catch、throw参数化类型对象
    • 重载的方法里不能有两个相同的原始类型的方法
  • 相关阅读:
    容器运行时与k8s概述
    若依 vue版 刷新页面 404 回到网站首页 index页面的问题
    深入了解GCC编译过程
    Day15: C++之STL容器(3/3)
    【react】精选5题
    Vue学习笔记之搭建环境 (一)
    今天是新的一天
    【10.28】【VP】Codeforces Round #743 (Div. 2)
    【第四周】程序的控制结构
    能源园区可视化管理系统
  • 原文地址:https://blog.csdn.net/xianghanscce/article/details/126697531