JVM中的方法调用

本文详细探讨了JVM中的方法调用,包括重载、重写的概念与区别,静态绑定与动态绑定的原理,以及invoke系列指令在JVM中的应用。此外,还深入解析了方法表、虚方法和内联缓存等关键概念,揭示了JVM如何实现高效的方法调用和多态性。
摘要由CSDN通过智能技术生成

转载请注明链接:https://blog.csdn.net/feather_wch/article/details/82564060

JVM中的方法调用

版本:2018/9/10-1(23:59)


问题汇总

  1. 可变长参数方法的重载
  2. 官方文档建议避免重载可变长参数方法
  3. 什么是重载?
  4. 如何绕开多个方法名字相同、参数类型相同的限制?
  5. 当一个类(具有多个方法,方法名相同、参数类型相同、但是返回值类型不同)出现在Java编译器的用户路径上时,如何确定应该调用哪个方法?
  6. 重载方法的识别是在哪个阶段完成的?
  7. Java编译器如何根据传入参数的声明类型来选取重载方法的?
  8. 声明类型和实际类型的区别?
  9. Java编译器在同一个阶段中找到了多个适配的方法,如何选择一个最合适的方法?
  10. 重载对于从父类继承来的非私有同名方法有效吗?
  11. JVM中不存在重载这一概念
  12. 如果子类定义的方法和继承自父类的方法同名,但是参数类型相同,这两个方法有什么关系?
  13. 父类和子类具有两个同名方法,都是静态方法,都是public。子类中的方法会隐藏了父类中的方法。
  14. 重写是什么?
  15. 方法重写是如何体现了Java的多态?
  16. JVM是如何识别方法的?关键在于三部分
  17. 方法描述符是什么?
  18. 如果一个类中出现了方法名相同,方法描述符相同的方法,会在类加载的什么阶段报错?
  19. JVM和Java语言规范对于方法的限制有哪些不同处?
  20. JVM的重写和Java语言的重写并不完全相同
  21. 什么是桥接方法?编译器如何通过生成桥接方法解决了Java和JVM重写语义不同的问题?
  22. 什么是静态绑定?什么是编译时多态?
  23. 什么是动态绑定?
  24. 对于JVM,什么是真正的静态绑定?
  25. 对于JVM,什么是真正的动态绑定?
  26. Java字节码中与调用相关的指令一共有五种
  27. invokeinterface实例
  28. invokestatic实例
  29. invokevirtual实例
  30. invokespecial实例
  31. invokeastatic和invokespecial,JVM能直接识别具体的目标方法.
  32. invokevirtual和invokeinterface,JVM需要在执行中,根据调用者的动态类型,来确定目标方法。
  33. 符号引用的作用?
  34. 符号引用存储在哪里?
  35. 符号引用的分类
  36. 实例中的符号引用
  37. 符号引用什么时候需要被替换为实际引用?
  38. JVM如何解析非接口符号引用,并替换为实际引用?
  39. 非接口符号引用的解析过程所得到的结论
  40. 隐藏和重写的区别
  41. JVM如何解析接口符号引用,并替换为实际引用?
  42. 实际引用是什么?
  43. 如何将java文件翻译成字节码文件
  44. 虚方法是什么?JVM中的虚方法调用?
  45. 类有一个非静态的public方法,该方法是否是虚方法?
  46. 虚方法和设计模式的关系?设计模式为什么需要大量采用虚方法来实现多态?
  47. 虚方法的性能低下?
  48. 哪些场景下虚方法的调用开销可以完全消除?
  49. 为什么JVM中虚方法调用的开销很低?
  50. 虚方法的性能消耗在哪?
  51. 需要动态绑定确定目标方法的方法都是虚方法
  52. 静态绑定的都是非虚方法
  53. 虚方法中也会涉及到静态绑定?虚方法指向的是final方法会怎么样?
  54. JVM中如何去提高动态绑定的性能消耗?
  55. 方法表的作用
  56. 方法表是何时构造的?类加载的准备阶段做了哪些事情?
  57. 方法表的底层实现
  58. 方法表中会存储private方法,或者static方法?
  59. 子类的方法表中是否包含父类方法表中的所有方法?
  60. 方法表的实例
  61. 方法表的动态绑定和静态绑定相比有哪些开销?
  62. 动态绑定的内存解引用操作的性能损耗可以忽略不计吗?
  63. Java栈帧是什么?何时创建并且初始化的?
  64. 方法表就是存储类的所有方法的表?
  65. 内联缓存是什么?
  66. 针对多态的优化手段中,具有单态、多态和超多态
  67. 如何区分多态和超多态?
  68. 内联缓存有几种?
  69. JVM采用哪种内联缓存方式?
  70. 如何没有命中内联缓存,对于内联缓存中的内容,JVM会如何处理?
  71. 内联缓存并不是真正的内联,依旧有固定开销。
  72. getter/setter等方法的固定开销超过了方法本身,这就需要方法内联的优化
  73. HotSpot没有多态内联缓存?
  74. 单态内联缓存和超多态内联缓存的性能差距?

重载(11)

1、什么是重载?

  1. Java中,如果同一个类中有多个方法:名字相同,参数类型相同。会无法通过编译。
  2. 如果想要在同一个类中定义名字相同的方法,参数类型必须不同。
  3. Java根据参数类型的不同,去选择对应的方法,称之为重载。

2、如何绕开多个方法名字相同、参数类型相同的限制?

  1. 可以通过字节码工具绕开
  2. 编译完成后,再向class文件中添加方法名相同、参数类型相同、但是返回值类型不同的方法。

3、当一个类(具有多个方法,方法名相同、参数类型相同、但是返回值类型不同)出现在Java编译器的用户路径上时,如何确定应该调用哪个方法?

  1. 目前java编译器会直接选取第一个方法名以及参数类型匹配的方法
  2. 并且根据返回值类型,判断是否可以通过编译,是否需要进行值转换

4、重载方法的识别是在哪个阶段完成的?

编译阶段

5、Java编译器如何根据传入参数的声明类型来选取重载方法的?

  1. 第一阶段:在不考虑对基本类型自动装拆箱,以及可变长参数的情况下选取
  2. 第二阶段:没有找到,在允许自动装拆箱,不允许可变长参数的情况下选取
  3. 第三阶段:还没找到,在允许自动装拆箱,允许可变长参数的情况下选择

6、声明类型和实际类型的区别?

  1. 声明类型:(Object)str,声明类型就是Object类型。
  2. 实际类型:(Object)str,实际类型是String
String str = "str";
// 声明类型为String
invoke(str, 1);
// 声明类型为Object
invoke((Object)str, 2);

7、Java编译器在同一个阶段中找到了多个适配的方法,如何选择一个最合适的方法?

  1. 这个符合程度的决定性因素就是形式参数类型的继承关系
  2. 比如传入参数null,可以是Object,也可以是String。因为String是子类,所以Java编译器认为String更符合。
public static void invoke(Object obj) {
        System.out.println("Object");
}
public static void invoke(String s) {
        System.out.println("String");
}
// null可以是Object,也可以是String
invoke(null);

8、重载对于从父类继承来的非私有同名方法有效吗?

  1. 子类具有一个方法,和继承自父类的方法,名称相同,参数类型不同。这就属于重载。

9、JVM中不存在重载这一概念

  1. 重载方法的区分处于编译阶段

可变长参数的方法重载

10、可变长参数方法的重载

void invoke(Object obj, Object... args) { ... }
void invoke(String s, Object obj, Object... args) { ... }

invoke(null, 1);// 调用第二个 invoke 方法
invoke(null, 1, 2);// 调用第二个 invoke 方法 invoke(null, 1, 2);
invoke(null, new Object[]{
  1});// 调用第一个 invoke 方法 ,只有手动绕开可变长参数的语法糖,才能调用第一个 invoke 方法
invoke((Object)null, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值