zoukankan      html  css  js  c++  java
  • java 泛型的类型擦除与桥方法

    泛型类

    ——代码参考:java核心技术 卷1 第十版

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class Pair<T>
    {
      private T first;
      private T second;
     
      //构造器
      public Pair()  { first = null; second = null;}
      public Pair(T first , T second )  {this.first = first; this.second = second;}
     
      //get方法
      public T getFirst()    {return first; }
      public T getSecond ()    {return second;}
     
      //set方法
      public void setFirst(T newValue)  { first =newValue; }
      public void setSecond (T newValue)   { second = newValue; }
    }

      

    泛型方法

    1
    2
    3
    4
    5
    class A
    public static <T> T get(T a)
    {
        return a;
    }

      泛型方法可以定义在普通类中,也可定义在泛型类中。

    类型擦除(Type Erasure)

    以下内容参考自—— [Java泛型与桥方法]

    JVM并不知道泛型的存在,因为泛型在编译阶段就已经被处理成普通的类和方法; 处理机制是通过类型擦除,擦除规则:

    • 若泛型类型没有指定具体类型,用Object作为原始类型;
    • 若有限定类型< T exnteds XClass >,使用XClass作为原始类型;
    • 若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;

    例如:上述泛型类Pair编译后的结果为

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public class Pair
    {
        private Object first=null;
        private Object second=null;
     
        public Pair(Object fir,Object sec)
         {
             this.first=fir;
             this.second=sec;
         }
       public Object getFirst()
       {
         return this.first;
       }
       public void setFirst(Object fir)
       {
            this.first=fir;
       }
    }

      类型擦擦会带来一些问题,比如当一个类实现了一个参数化的接口或是继承了一个参数化的类时。

    1
    2
    3
    4
    class SonPair extends Pair<String> //继承类一个泛型类
    {
         public void setFirst(String fir){....}//重写了父类的方法
    }

      Pair在编译的时候已经被类型擦除,Pair的setFirst方法变为了setFirst(Object fir),这样SonPair的setFirst(Stirng fir)方法就无法覆盖父类中的setFirst(Object fir)方法,因为参数不同,不是同一个方法。 如下所示,SonPair中会出现两个方法:

    1
    2
    public void setFirst(String fir){....}
    public void setFirst(Object fir){....}

      那么具体应该调用哪一个方法呢? 为了解决这个问题,jvm引进了桥方法的概念

    桥方法

    上一节中的两个方法被编译器变成了这样:

    1
    2
    3
    4
    5
    6
    7
    public void setFirst(String fir){....} //这里什么都不变
     
    //为该方法添加了一些东西,该方法就被称为“桥方法”
    public void setFirst(Object fir)
    {
         setFirst((String) fir);//桥内部调用的是子类中定义的setFirst(String fir)方法
    }
  • 相关阅读:
    第 425 期 Python 周刊
    第 423 期 Python 周刊
    第423期 Python 周刊
    Python Weekly 422
    第421期 Python 周刊
    第420期 Python 周刊
    LeetCode 3: 无重复字符的最长子串 Longest Substring Without Repeating Characters
    Python Weekly 419
    LeetCode 771: 宝石与石头 Jewels and Stones
    LeetCode 652: 寻找重复的子树 Find Duplicate Subtrees
  • 原文地址:https://www.cnblogs.com/wt88/p/9624350.html
Copyright © 2011-2022 走看看