<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    [轉(zhuǎn)] Java bridge methods explained

    原文:
    http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html

    Bridge methods in Java are synthetic methods, which are necessary to implement some of Java language features. The best known samples are covariant return type and a case in generics when erasure of base method's arguments differs from the actual method being invoked.

    Have a look at following example:

    public class SampleOne {
    public static class A<T> {
    public T getT() {
    return null;
    }
    }

    public static class  B extends A<String> {
    public String getT() {
    return null;
    }
    }
    }

    Which in reality is just an example of covariant return type and after erasure will look like following snippet:

    public class SampleOne {
    public static class A {
    public Object getT() {
    return null;
    }
    }

    public static class  B extends A {
    public String getT() {
    return null;
    }
    }
    }

    And after the compilation decompiled result class "B" will be following:
    public class SampleOne$B extends SampleOne$A {
    public SampleOne$B();

    public java.lang.String getT();
    Code:
    0:   aconst_null
    1:   areturn
    public java.lang.Object getT();
    Code:
    0:   aload_0
    1:   invokevirtual   #2// Call to Method getT:()Ljava/lang/String;
    4:   areturn
    }

    Above you can see there is new synthetic method "java.lang.Object getT()" which is not present in source code. That method acts as bridge method and all is does is delegating invocation to "java.lang.String getT()". Compiler has to do that, because in JVM method return type is part of method's signature, and creation of bridge method is the way to implement covariant return type.

    Now have a look at following example which is generics-specific:
    public class SampleTwo {
    public static class A<T> {
    public T getT(T args) {
    return args;
    }

    }


    public static class B extends A<String> {
    public String getT(String args) {
    return args;
    }

    }

    }

    after compilation class "B" will be transformed into following:
    public class SampleThree$B extends SampleThree$A{
    public SampleThree$B();

    public java.lang.String getT(java.lang.String);
    Code:
    0:   aload_1
    1:   areturn

    public java.lang.Object getT(java.lang.Object);
    Code:
    0:   aload_0
    1:   aload_1
    2:   checkcast       #2//class java/lang/String
    5:   invokevirtual   #3//Method getT:(Ljava/lang/String;)Ljava/lang/String;
    8:   areturn
    }

    here, the bridge method, which overrides method from base class "A", not just calling one with string argument (#3), but also performs type cast to "java.lang.String" (#2). It means, that if you will execute following code, ignoring compiler's "unchecked" warning, the result will be ClassCastException thrown from the bridge method:
    A a = new B();
    a.getT(
    new Object()));

    These two examples are the best known cases where bridge methods are used, but there is, at least, one more, where bridge method is used to "change" visibility of base class's methods. Have a look at following sample and try to guess where compiler may need the bridge method to be created:
    package samplefour;

    public class SampleFour {
    static class A {
    public void foo() {
    }

    }

    public static class C extends A {

    }

    public static class D extends A {
    public void foo() {
    }

    }

    }
    If you will decompile class C, you will see method "foo" there, which overrides method from base class and delegates to it:
    public class SampleFour$C extends SampleFour$A{

    public void foo();
    Code:
    0:   aload_0
    1:   invokespecial   #2//Method SampleFour$A.foo:()V
    4:   return

    }

    compiler needs that method, because class A is not public and can't be accessed outside it's package, but class C is public and all inherited method have to become visible outside the package as well. Note, that class D will not have bridge method, because it overrides "foo" and there is no need to "increase" visibility.
    It looks like, that type of bridge method, was introduced after bug which was fixed in Java 6. It means that before Java 6 that type of bridge method is not generated and method "C#foo" can't be called from package other than it's own via reflection, so following snippet causes IllegalAccessException, in cases when compiled on Java version < 1.6:
    package samplefive;

    SampleFour.C.
    class.getMethod("foo").invoke(new SampleFour.C());
    Normal invocation, without using reflection, will work fine.

    Probably there are some other cases where bridge methods are used, but there is no source of information about it. Also, there is no definition of bridge method, although you can guess it easily, it's pretty obvious from examples above, but still would be nice to have something in spec which states it clearly. In spite of the fact that method Method#isBridge() is part of public reflection API since Java1.5 and bridge flag is part of class file format, JVM and JLS specifications do not have any information what exactly is that and do not provide any rules when and how it should be used by compiler. All I could find is just reference in "Discussion" area here.

    posted on 2011-08-20 10:19 happyenjoylife 閱讀(441) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    <2011年8月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    統(tǒng)計

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 伊人久久国产免费观看视频| 免费视频成人手机在线观看网址| 亚洲日韩在线观看| 亚洲免费在线播放| 亚洲精品国产首次亮相 | 在线日韩日本国产亚洲| 国产成人久久AV免费| 亚洲熟妇丰满xxxxx| 中文字幕亚洲综合久久菠萝蜜 | 亚洲影视一区二区| 国产国产人免费视频成69大陆| 中文字幕无线码中文字幕免费 | 亚洲精品无码久久久久A片苍井空| 国产a v无码专区亚洲av| 日韩精品免费一级视频| 人妻仑乱A级毛片免费看| 亚洲国产精品综合久久久| 亚洲国产日韩成人综合天堂| 在线看免费观看AV深夜影院| 一区二区三区免费视频观看| 亚洲色图激情文学| 亚洲成在人线av| 国产三级免费电影| 在人线av无码免费高潮喷水| 精品97国产免费人成视频| 亚洲愉拍一区二区三区| 亚洲AV日韩AV永久无码久久 | 亚洲欧洲免费无码| 日韩精品极品视频在线观看免费| 日日摸日日碰夜夜爽亚洲| 亚洲人成毛片线播放| 久久香蕉国产线看观看亚洲片| 国产免费AV片无码永久免费| 国产成人福利免费视频| 免费观看一区二区三区| 污视频网站免费观看| 久久亚洲国产成人影院| 亚洲精品午夜视频| 亚洲av无码一区二区三区网站| 亚洲国产成人五月综合网| 大陆一级毛片免费视频观看 |