• Thomas 置顶
    2018-07-27
    看明白了......这篇真好
    
     23
  • 永烁星光
    2018-07-29
    写的有点晦涩难懂,看了好几遍,还是有点迷糊
     2
     142
  • 胡小榕
    2018-12-26
    请不要用中文定义类/变量,有强迫症
     1
     51
  • godtrue
    2018-07-30
    1:方法重载
    方法名相同、方法参数类型不同(其中包括参数的个数、类型、次序,三者之中只要有一个不同就行)。以前的理解方法重载是在一个类内,今天读后感觉类间有继承关系也是存在方法重载的,需要验证一下?

    2:方法重写
    方法名相同、方法参数类型相同、方法返回值相同,类之间有继承关系,便构成方法重写。
    这个概念和之前一样,不过老师强调了父类中的方法是飞私有、非静态的,这个有待验证一下?

    3:JVM定位目标方法的关键是类名+方法名+方法参数类型+方法返回值类型,于是就出现了两种JVM找目标方法的方式,静态绑定、动态绑定

    4:静态绑定
    在解析时JVM便知道该调用那个目标方法

    5:动态绑定
    在运行时JVM需要根据对应的类类型来具体定位应该调用那个目标方法。对于方法重写,对应的类会拥有一个方法表(一个二维数组表,给方法标上序号,重写的方法序号一致)

    听了几遍,也看了几遍,感觉对具体细节还是不清楚,比如:
    1:静态绑定具体咋实现的?
    2:方法表在那里?啥时候创建的?咋和具体的类关联起来的呢?
    可能篇幅有限啊!总体老师讲的很好,有些细节没讲到,我的感觉!
    展开
     2
     32
  • jiaobuchongจุ๊บ
    2018-11-06
    参考老师最后的例子,写了博客总结了一下:https://blog.csdn.net/jiaobuchong/article/details/83722193,欢迎拍砖。

    作者回复: 赞!

    
     22
  • 蒙奇•D•273°
    2018-08-15
    没完全理解。有个问题,接口符号指向接口方法,但是接口是没有实现的,他的实现在其实现类里面,我理解最终应该指向接口的实现类
     2
     10
  • Askerlve
    2018-07-28
    任督二脉就靠这个系列打通了~🤑
    
     9
  • ...
    2019-01-03
    没完全理解,上来开头没有好的引入。
    
     7
  • 小贝_No_7
    2018-07-28
    如果这两个方法都是静态的,那么子类中的方法隐藏了父类中的方法。

    这句没太明白,这个(隐藏)是否有更深一层的意义?
     3
     7
  • 三木子
    2018-07-27
    需要看三遍
    
     6
  • Kenneth
    2018-08-08
    老师你好,课后的例子编译不通过,提示有重复的类Merchant,另外,提示找不到类VIP。可以指导一下,课后的练习题的具体操作教程吗?非常感谢🙏!
     1
     4
  • 永烁星光
    2018-07-29
    唯一的例外在于,如果虚拟机能够确定目标方法有且仅有一个,比如说目标方法被标记为 final[3][4]
    请问这里的final[3][4] 是什么意思
    
     4
  • 东方
    2018-07-28
    好顶赞👍
    
     4
  • 路阳
    2018-10-10
    符号引用转实际引用时,对于非接口符号引用的第三条,在该类及父类中没有找到目标方法,便会在其直接和间接实现的接口中查找。如果存在多个符合条件的方法,并不会随机选择一个,而是优先选择拥有最具体实现的默认方法的接口,即如果 B 继承了 A,那么 B 就比 A 更加具体。代码如下:
     interface A {
        default void hello() {
            System.out.println("Hello form A");
        }
    }
    interface B extends A {
        default void hello() {
            System.out.println("Hello from B");
        }
    }
    public class C implements A,B {
        public static void main(String[] args) {
            new C().hello(); //输出 Hello from B
        }
    }

    在 java 里如果无法判断谁更具体,则需要在 C 里面显示的覆盖 hello()方法。
    展开
    
     3
  • 东方
    2018-08-11
    Merchant类中actionPrice方法返回值类型为Number
    NaiveMerchant类中actionPrice方法返回值类型为Double

    NaiveMerchant类生成的字节码中有两个参数类型相同返回值类型不同的actionPrice方法
     Method actionPrice:(DLCustomer;)Ljava/lang/Double;
     Method actionPrice:(DLCustomer;)Ljava/lang/Number; // 桥接到返回值为double的方法 flags: ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

     方法返回值不同为何也要产生桥接方法呢? 为了保证重写语义?

    不知为何javac在编译

    NaiveMerchant naiveMerchant = new NaiveMerchant();
    Number number = naiveMerchant.actionPrice(1d, null) // 特意要求Number类型的返回值(方法描述符)

    时,总invokevirtual到Method NaiveMerchant.actionPrice:(DLCustomer;)Ljava/lang/Double,这又是为什么呢?

    附jdk版本
    java version "1.8.0_172"
    Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
    GraalVM 1.0.0-rc5 (build 25.71-b01-internal-jvmci-0.46, mixed mode)


    展开

    作者回复: 1 对的,为了保证重写语义。
    2 生成的桥接方法还有一个acc_synthetic标记,代表对程序不可见。因此javac不能直接选取那个方法。

    
     3
  • Nevermore
    2018-12-26
    由于对重载方法的区分在编译阶段已经完成,我们可以认为 Java 虚拟机不存在重载这一概念。

    为什么这么说?编译阶段和虚拟机有什么联系?
     2
     2
  • 小乙哥
    2018-12-05
    类名,方法名,参数名可以不用中午吗?
    
     2
  • lxz
    2018-08-02
    接口的符号引用这部分没看懂,字节码确实是能看到invokeinterface指向了接口的方法,但是实际执行的时候,是怎么做的呢,应该执行具体实现类的字节码啊。
    另外,一个小问题,方法字节码code段内,有些类似行号的数字,在每行开头,后面跟着一个冒号,是什么意思,是行号吗?
    
     2
  • L.B.Q.Y
    2018-07-27
    开篇例子中的invoke(null,1)之所以选择第二个invoke(),按照重载方法选择三步骤的布骤二,不考虑变长参数但是考虑基本类型的拆装箱,正好匹配第二个invoke.
    而invoke(null,1,2)按照重载方法选择三步骤的步骤三,两个invoke方法都匹配,考虑类型的继承关系,第二个invoke更恰当。
    
     2
  • 杨春鹏
    2018-07-27
    老师,关于方法调用的字节码指令中的invokespecial:调用实现接口的默认方法。
    我测试了一下,发现子类中调用实现接口的默认方法还是使用的invokeinrerface。

    作者回复: 多谢指出!这里我指的是使用super关键字调用所实现接口的默认方法。

     1
     2
我们在线,来聊聊吧