5

在 Java 中,所有公共非静态方法都是虚拟的。这意味着调用哪个方法取决于运行时(动态绑定)。在 C++ 中,虚函数(动态绑定)是通过使用 vpointer 和 vtable 来实现的。我想知道Java是如何实现的。Java 是否也像 C++ 一样使用 vpointer 和 vtable 或其他一些技术来知道在运行时调用哪个方法?

4

4 回答 4

5

vtables,如https://wikis.oracle.com/display/HotSpotInternals/VirtualCalls中所述

[编辑 Tomasz 在问题评论中提出了一个很好的观点——这是针对 Oracle 的热点]

于 2012-08-18T19:22:12.123 回答
0

既然这是 Java 虚拟机的世界,故事就不那么简单了。您能做的最好的事情就是了解所有各种特殊情况所采用的所有数十种技巧。这不是一个糟糕的起点:内联缓存

于 2012-08-18T19:25:43.500 回答
0

基本上,它是(概念上)使用虚函数表实现的,并对其进行索引。但是有许多曲折,特别是“invokespecial”调用和接口调用,需要额外/不同的处理。

在实践中,大量的数据被缓存,以提高调用效率。

于 2012-08-18T19:32:48.300 回答
0

并非所有非静态方法都在运行时绑定。在某些情况下,可以在编译时确定需要调用哪个版本的方法。特别是,当编译器可以 100% 确定需要调用哪个方法时。一种这样的简单情况:

public class Foo {
   public final void foo() { ... }

   public void bar() { ... }

   public void bar(String s) { ... }
}

Foo foo = new Foo();
// All three of these could would be bound at compile time.
foo.foo();
foo.bar();
foo.bar("baz");

还有一些基于重载的情况,可以确定编译时绑定。我不是 100% 确定所有不同的情况是什么,但有一些。

这是一篇关于这个主题的好文章:

http://www.dzone.com/links/r/difference_between_static_and_dynamic_binding_in.html

于 2012-08-19T04:43:42.430 回答