Lem*_*mmy 7 java overriding run-time-polymorphism
运行时多态性是否总是在方法覆盖时发生,还是只有在方法覆盖期间将子类对象分配给超类变量后调用方法才会发生?
class A {
public void myFunc() {
System.out.println("Something");
}
}
class B extends A {
public void myFunc() {
System.out.println("Something else");
}
public static void main (String args[]) {
A obj = new B();
obj.myFunc(); //Is only this call resolved at run time?
A obj2 = new A();
obj2.myFunc(); //Or is this call too resolved at run time?
B obj3 = new B();
obj3.myFunc(); //Is this call resolved at compile time?
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
在方法覆盖中,方法解析始终由 JVM 基于运行时对象负责。是的,所有这些调用都会在运行时得到解决。
A obj = new B();
obj.myFunc();
Run Code Online (Sandbox Code Playgroud)
A obj2 = new A();
obj2.myFunc();
B obj3 = new B();
obj3.myFunc();
编译器实际上是否能够优化这三个方法调用中的任何一个或全部,并在编译时或将来的某个实现中解析这些调用是无关紧要的:所有三个方法调用都是运行时多态性的示例,也称为动态调度,这是对比的所谓的静态多态性,也称为方法重载,是一个具有多个同名但参数类型不同的方法的类。
这是一个小的 Java 程序:
public class Test {
public void foo(String inputString)
{
System.out.println(inputString);
}
public static void main(String[] args) {
Test test = new Test();
test.foo("a"); # very obvious method invocation
}
}
Run Code Online (Sandbox Code Playgroud)
人们非常清楚在运行时将调用什么方法。这是反汇编的字节码:
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public void foo(java.lang.String);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_1
4: invokevirtual #3 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
7: return
public static void main(java.lang.String[]);
Code:
0: new #4 // class Test
3: dup
4: invokespecial #5 // Method "<init>":()V
7: astore_1
8: aload_1
9: ldc #6 // String a
11: invokevirtual #7 // Method foo:(Ljava/lang/String;)V
14: return
}
Run Code Online (Sandbox Code Playgroud)
指令11是虚拟方法的运行时分派。
但正如我所说,即使在未来的某些编译器实现中,这被优化为不同的调用,那也只是一个实现细节。
| 归档时间: |
|
| 查看次数: |
616 次 |
| 最近记录: |