我拟定了两种情况,它们之间的奇怪差异让我有些难过。我将尝试在下面的代码中详细说明它们。
情况一:
public void doSomething(Object obj) {
//do something with obj
}
public void doSomething(String str) {
//do something similar to str, but apply some custom
//processing for String's
}
Object o = new String("s");
doSomething(o); // this will use the Object version...
情况二:
class Dog {
void makeSound() {
System.out.println("woof");
}
}
class Chihuahua extends Dog {
void makeSound() {
System.out.println("yip");
}
}
Dog dog = new Chihuahua();
dog.makeSound(); //will print 'yip', the Chihuahua version...
为什么在情况一中没有使用参数的运行时类型,而在情况二中却使用了?我知道这些例子实际上是不同的东西,但我更好奇这里“幕后”发生的事情。
最佳答案
在第一个示例中,方法签名是在编译时从多个重载签名中选择的。 Java 语言规范说这是基于变量的静态类型完成的。
在第二个示例中,给定方法签名的实现是在运行时根据虚方法分派(dispatch)选择的。这是基于包含方法定义的类的运行时类型完成的。
关于Java——运行时类型差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5998953/