Java 中的静态绑定和动态绑定
Static binding and dynamic binding in Java
起初我是初学者
看了那么多教程,读了那么多例子,甚至从JLS上也试图理解这个主题,但我仍然有一些困惑或误解。
让我向您展示我无法理解的问题。
假设我们有三个 类 Parent
, Child1
, Child2
如下:
class Parent {
void doSmth(Object o) {
System.out.println("Parent.doSmth");
}
}
class Child1 extends Parent {
void doSmth(Object o) {
System.out.println("Child1.doSmth");
}
}
class Child2 extends Parent {
void doSmth(String s) {
System.out.println("Child2.doSmth");
}
}
class Test {
public static void main(String[] args) {
Parent p1 = new Child1();
Parent p2 = new Child2();
p1.doSmth("String");
p2.doSmth("String");
}
}
我的理解是,因为p1
和p2
的引用来自Parent
类型,那么doSmth(Object)
只会对编译器可见。
对于p1.doSmth("String");
,编译器没有绑定它,因为有一个覆盖方法,所以它只是让 JVM 在运行时绑定它(动态绑定)。
而对于 p2.doSmth("String");
,编译器对其进行了绑定,因为它没有找到覆盖它的方法(静态绑定)。
问题是,我说的是真的吗?还是我有误解?如果它是假的,那么请告诉我在这种情况下编译器会采取什么步骤??
如果它是真的,编译器怎么能期望 p1.doSmth
它有一个覆盖方法(虽然它不知道它是真实类型),而在 p2.doSmth
中它只是绑定它?我错过了什么吗??
对不起,这真让我头疼..
试图总结讨论。根据需要进行编辑。
Java 中的静态绑定发生在编译时,而动态绑定发生在运行时。
在编译时,p1 和 p2 都是 Parent 的类型并且 Parent 有 doSmth(Object) 方法因此这两行绑定到相同的方法。
p1.doSmth("String");
p2.doSmth("String");
在运行时,动态绑定开始发挥作用。
p1 是 Child1 的实例,而 Child1 已覆盖 doSmth(Object),因此使用 Child1 的实现。
p2 是 Child2 的实例并且 Child2 不会覆盖 doSmth(Object) 因此调用从 Parent 继承的方法的实现。
起初我是初学者
看了那么多教程,读了那么多例子,甚至从JLS上也试图理解这个主题,但我仍然有一些困惑或误解。
让我向您展示我无法理解的问题。
假设我们有三个 类 Parent
, Child1
, Child2
如下:
class Parent {
void doSmth(Object o) {
System.out.println("Parent.doSmth");
}
}
class Child1 extends Parent {
void doSmth(Object o) {
System.out.println("Child1.doSmth");
}
}
class Child2 extends Parent {
void doSmth(String s) {
System.out.println("Child2.doSmth");
}
}
class Test {
public static void main(String[] args) {
Parent p1 = new Child1();
Parent p2 = new Child2();
p1.doSmth("String");
p2.doSmth("String");
}
}
我的理解是,因为p1
和p2
的引用来自Parent
类型,那么doSmth(Object)
只会对编译器可见。
对于p1.doSmth("String");
,编译器没有绑定它,因为有一个覆盖方法,所以它只是让 JVM 在运行时绑定它(动态绑定)。
而对于 p2.doSmth("String");
,编译器对其进行了绑定,因为它没有找到覆盖它的方法(静态绑定)。
问题是,我说的是真的吗?还是我有误解?如果它是假的,那么请告诉我在这种情况下编译器会采取什么步骤??
如果它是真的,编译器怎么能期望 p1.doSmth
它有一个覆盖方法(虽然它不知道它是真实类型),而在 p2.doSmth
中它只是绑定它?我错过了什么吗??
对不起,这真让我头疼..
试图总结讨论。根据需要进行编辑。
Java 中的静态绑定发生在编译时,而动态绑定发生在运行时。
在编译时,p1 和 p2 都是 Parent 的类型并且 Parent 有 doSmth(Object) 方法因此这两行绑定到相同的方法。
p1.doSmth("String");
p2.doSmth("String");
在运行时,动态绑定开始发挥作用。
p1 是 Child1 的实例,而 Child1 已覆盖 doSmth(Object),因此使用 Child1 的实现。
p2 是 Child2 的实例并且 Child2 不会覆盖 doSmth(Object) 因此调用从 Parent 继承的方法的实现。