Java - 虚拟方法

sgo*_*les 17 java

虚拟函数如何在继承中的幕后工作?编译器是否特别处理虚函数?

Kev*_*ell 38

java中的所有方法都是默认的虚拟方法.这意味着在继承中使用任何方法都可以被覆盖,除非该方法被声明为final或static.

  • 非静态(实例)方法始终是虚拟的.静态(类)方法永远不是虚拟的.您是对的,因为在派生类中不能覆盖声明为final的虚方法. (2认同)

use*_*421 14

'Virtual'是一个C++术语.Java中没有虚拟方法.有一些普通的方法,它们是运行时多态的,而静态或最终的方法则不是.

  • 我没有downvote但是我认为声明"Java中的所有方法都是默认的虚拟"更好.虽然Java中没有特定的"虚拟"修饰符,但基本概念仍然相同.声称没有虚拟方法有点误导恕我直言 (13认同)
  • @EJP您的答案有助于理解Java的概念基础.但是,在低级别,不可能忽略虚拟方法的概念,因为它是由JVM和DVM在引擎盖下实现的(并在各自的字节码中明确声明).所以,一旦你深入了解,真正需要了解虚函数是什么. (7认同)
  • @ChrisWue但你的版本不是真的.静态方法在任何意义上都不是虚拟的,也不是运行时多态的.我的版本捕获了:你的版本没有.奥卡姆的剃刀决定你不要不必要地增加概念.在讨论Java时,不需要"虚拟"这个词,就像语言本身一样. (2认同)

And*_*are 13

是的,编译器和运行时对虚拟方法的处理方式不同.JVM专门使​​用虚方法表进行虚方法调度:

对象的分派表将包含对象的动态绑定方法的地址.通过从对象的分派表中获取方法的地址来执行方法调用.对于属于同一类的所有对象,调度表是相同的,因此通常在它们之间共享.属于类型兼容类的对象(例如继承层次结构中的兄弟节点)将具有相同布局的调度表:给定方法的地址将出现在所有类型兼容类的相同偏移处.因此,从给定的调度表偏移量获取方法的地址将获得与该对象的实际类对应的方法.