Java 在这种情况下,JVM如何处理动态调度?
给定以下源和输出: 资料来源:Java 在这种情况下,JVM如何处理动态调度?,java,jvm,polymorphism,overriding,dispatch,Java,Jvm,Polymorphism,Overriding,Dispatch,给定以下源和输出: 资料来源: public class A { public void foo() { bar(); } public void bar() { System.out.println ("in A's bar() method"); } } public class B extends A { @Override public void foo() { super.foo(); // Do some sp
public class A
{
public void foo()
{
bar();
}
public void bar()
{
System.out.println ("in A's bar() method");
}
}
public class B extends A
{
@Override
public void foo()
{
super.foo();
// Do some specialized B stuff
}
@Override
public void bar()
{
System.out.println ("in B's bar() method");
}
}
public class Main
{
public static void main (String... args)
{
B b = new B();
b.foo();
}
}
输出:
B的bar()方法中的
有人能向我解释一下JVM是如何聪明到可以在这种情况下多态地调用B的(而不是A的)bar()方法的吗?我想知道在幕后发生了什么样的动态调度魔术
更新:如果我不够清楚,我基本上知道发生了什么,我正在寻找JVM如何让它在幕后发生的具体细节。目前的答案过于简单化
更新2:可能我不够清楚。当调用b.foo()
时,则调用super.foo()
,然后在类A的foo()
中调用bar()
。特别调用super.foo()
时调用的bar()
如何不调用类A的bar()
方法,因为super
关键字明确指定了类A?JVM必须通过哪些步骤来解决这个问题
另外,这是否意味着从自己的类中调用公共方法通常是个坏主意,因为它们可以通过这种方式被重写?Java在调用方法时使用对象的类型。
A b = new B();
b.foo();
假设您使用了上述代码。
在这里,您将创建一个类型为B的对象,并将其分配给类型为a的引用。由于对象类型为B,您将调用类B中的方法。即使您当前所在的构造函数或方法是在一个超类中定义的,对象的类型也不会改变。它仍然是B
类型的对象。这可以通过使用This
关键字来演示
此
引用当前对象。这与定义当前方法或构造函数的类不同
尝试在A
的构造函数或foo()
方法中键入以下内容:
System.out.println(this.getClass());
函数调用顺序是(从eclipse调试视图):
在线程调用super.foo()之后,JVM将检查B中是否有任何实现(因为我们仍然在堆栈中持有B.class),如果有,JVM将调用它
这个特性由JVM实现保证。它不是智能的,它只是这样设计的,就像C++的虚拟方法一样
希望有帮助。我知道您描述的情况,但这不是我要问的。谢谢你的回答,我照你说的做了;这既有趣又有帮助,但我仍在寻找更多关于引擎盖下发生的事情的细节。如果你有解决方案,请分享。我也在寻找这个问题的解决办法。“引擎盖下到底发生了什么”谢谢你的解释。如果您更详细地了解JVM如何检查B中的实现,并在这个程序的每个方法调用中遍历JVM所采取的步骤,我会接受您的答案。请查看我的更新。
1. B.foo() // super.foo()
2. B(A).foo() // bar()
3. B.bar()