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

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

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

    [轉] 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 閱讀(447) 評論(0)  編輯  收藏


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


    網站導航:
     

    導航

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

    統計

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 久久久久国色AV免费看图片| 日韩电影免费在线观看网站 | 九九99热免费最新版| 又爽又高潮的BB视频免费看| 亚洲av无码专区国产不乱码| 在线免费一区二区| 亚洲AV无码一区二区一二区| 国产男女猛烈无遮档免费视频网站| 亚洲国产成人综合精品| 国产精品免费_区二区三区观看| 亚洲av无码av在线播放| 亚洲av手机在线观看| 免费国产草莓视频在线观看黄| 亚洲毛片av日韩av无码| 国产无遮挡裸体免费视频在线观看 | 亚洲天堂一区二区三区| 国产精品免费一区二区三区四区| 亚洲无码黄色网址| 在线观看免费黄网站| 亚洲国产精品久久久久网站| 最近2018中文字幕免费视频| 亚洲一区二区三区无码国产| 日韩高清在线高清免费| aa在线免费观看| 亚洲精品乱码久久久久久下载| 成年人视频在线观看免费| 色欲aⅴ亚洲情无码AV| 亚洲一区二区三区在线观看精品中文 | 69av免费视频| 亚洲一卡2卡三卡4卡无卡下载 | 色吊丝性永久免费看码| 国产亚洲人成无码网在线观看| 久久久精品2019免费观看 | 亚洲乱码在线观看| 亚洲精品WWW久久久久久| 国产精品99精品久久免费| 亚洲欧洲另类春色校园网站| 亚洲精品和日本精品| 久久精品人成免费| 黄网站色视频免费观看45分钟| 亚洲国产精品免费视频|