亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁(yè) > IT技術(shù) > 其他 > 正文

              泛型之橋接方法
              2022-08-29 23:57:52

              ?什么是橋接方法

                在 JDK1.5 中引入了泛型,泛型類型是基于原始類型、類型擦除原理進(jìn)行實(shí)現(xiàn)的。那么JDK1.5有了泛型怎么兼容JDK1.5之前的類?
                原始類型:Java總是會(huì)自動(dòng)的為泛型類型提供一個(gè)相應(yīng)的原始類型。所謂原始類型就是是指泛型的第一個(gè)限定類型(從左向右),無(wú)限定類型泛型的原始類型默認(rèn)為Object。
                類型擦除:Java中泛型的實(shí)現(xiàn)原理是類型擦除(type erasure)。類型擦除是在編譯器進(jìn)行代碼編譯這個(gè)階段進(jìn)行的,在編譯的時(shí)候泛型的類型參數(shù)會(huì)被原始類型(raw type)所替代。
                橋接方法是在父類、子類的繼承場(chǎng)景中出現(xiàn)的。父類是泛型類,且在該類中存在泛型方法。子類繼承父類,并實(shí)現(xiàn)泛型方法。如果在子類實(shí)現(xiàn)中不包含父類經(jīng)過(guò)類型擦除后生成的原始類型方法,則編譯器會(huì)自動(dòng)將該原始類型方法添加到子類中。這個(gè)被添加的原始類型方法我們稱之為橋接方法。

              看個(gè)例子

               ?。?)首先定義一個(gè)父類接口SuperClass

              public interface SuperClass<T>{
                  void test(T t);
              }

                我們來(lái)看下字節(jié)碼文件??javap -verbose SuperClass.class,只有一個(gè)test方法。

              ?。?)定義一個(gè)子類實(shí)現(xiàn)類BaseClass

              public class BaseClass implements SuperClass<String>{
                  @Override
                  public void test(String s) {
                      
                  }
              }

                看下BaseClass的字節(jié)碼文件,發(fā)現(xiàn)類中多了一個(gè)方法 public void test(java.lang.Object);這個(gè)就是本文要討論的橋接方法。

                PS:ACC_BRIDGE 修飾符表示這是一個(gè)橋接方法。ACC_SYNTHETIC修飾符表示這個(gè)方法是由編譯器自動(dòng)生成的。

               ?

              (3)定義一個(gè)BaseClass的擴(kuò)展類SubClass(子類),擴(kuò)展其他方法

              public class SubClass extends BaseClass{
                  public void run() {
                      System.out.println("run---");
                  }
              }

                查看字節(jié)碼文件,只有一個(gè)run方法。

                

                SubClass重寫(xiě)父類test方法

              public class SubClass extends BaseClass{
                  public void run() {
                      System.out.println("run---");
                  }
                  @Override
                  public void test(String s) {
                      System.out.println("SubClass.test(s)");
                  }
              }

                再次查看字節(jié)碼文件,生成了橋接方法public void test(java.lang.Object);  

              ?

                那么我們是否可以推測(cè)出:橋接方法是伴隨泛型方法而生的,在繼承關(guān)系中,如果某個(gè)子類覆蓋了泛型方法,則編譯器會(huì)在該子類中自動(dòng)生成橋接方法。

              那么為什么要生成橋接方法?

                父接口SuperClass定義了test方法,SuperClass經(jīng)過(guò)類型擦除轉(zhuǎn)換為原始類型后,會(huì)生成 public void test(java.lang.Object); 方法,我們?cè)赟uperClass的子類定義了泛型的具體類型,導(dǎo)致子類中的 test方法變化為 public void test(String s);,
                那么此時(shí)父類的 public void test(java.lang.Object); 是沒(méi)有被實(shí)現(xiàn)的,為了解決這個(gè)問(wèn)題,Java 編譯器通過(guò)橋接的方式實(shí)現(xiàn)了 public void test(java.lang.Object); 方法。
                這樣就保證了SuperClass與子類具有相同的一致的方法 public void test(java.lang.Object); 。在訪問(wèn)泛型對(duì)象時(shí),通過(guò)父類方法 test進(jìn)行統(tǒng)一調(diào)用,而不需要關(guān)注子類的具體實(shí)現(xiàn)。

              橋接方法的執(zhí)行過(guò)程

                找個(gè)有橋接方法的類,我們看下字節(jié)碼文件, 比如BaseClass

                public void test(java.lang.Object); 這個(gè)方法真正執(zhí)行的是public void test(String s);?

              怎么判斷一個(gè)方法是否是橋接方法?

                通過(guò) method.isBridge() 可以判定是否為橋接方法。

                  public static void main(String[] args) throws Exception{
                      BaseClass baseClass = new BaseClass();
                      Method method1 = BaseClass.class.getMethod("test", String.class);
                      method1.invoke(baseClass,"ABC");
                      System.out.println(method1.isBridge());
                      Method method2 = BaseClass.class.getMethod("test", Object.class);
                      method2.invoke(baseClass,"ABC");
                      System.out.println(method2.isBridge());
                  }

              ?

              使用場(chǎng)景

                在 Mybatis中, MapperAnnotationBuilder 類的 parse 方進(jìn)行了橋接方法的判定。

                我們使用反射調(diào)用方法時(shí),也需要考慮橋接方法是否處理。

              ?

              ?

              ?

              ?

              ?

                

               

              ?

              本文摘自 :https://www.cnblogs.com/

              開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >