java中方法重载的行为

java中方法重载的行为,java,polymorphism,overloading,Java,Polymorphism,Overloading,我尝试了以下代码 public class HelloWorld { public void printData(Test t) { System.out.println("Reached 1"); } public void printData(newTest t) { System.out.println("Reached 2"); } public void printData(newTest1 t) {

我尝试了以下代码

public class HelloWorld {

    public void printData(Test t) {
        System.out.println("Reached 1");
    }

    public void printData(newTest t) {
        System.out.println("Reached 2");
    }

    public void printData(newTest1 t) {
        System.out.println("Reached 3");
    }

    public static void main(String args[]) {
        Test t1 = new Test();
        HelloWorld h = new HelloWorld();
        h.printData(t1);

        NewTest t2 = new NewTest();
        h.printData(t2);

        NewTest1 t3 = new NewTest1();
        h.printData(t3);

        Test t4 = new NewTest();
        h.printData(t4);

        Test t5 = new NewTest1();
        h.printData(t5);
    }
}
我有简单的课程

class Test {
}

class NewTest extends Test {
}

class NewTest1 extends Test {
}
我得到的结果是

Reached 1
Reached 2
Reached 3
Reached 1
Reached 1
从输出来看,当jvm决定执行哪个函数时,它只考虑引用的类型,而不考虑对象的实际类型


为什么会发生这种情况?为什么jvm不能考虑实际对象的类型而不是指向它的引用的类型?

函数重载是编译时多态性,这里编译器决定调用哪个版本的方法。对于编译器来说,很难知道运行时的实际对象,所以它会检查引用类型仅与要指向的对象无关。

函数重载是编译时多态性,在这里,编译器决定调用哪个版本的方法。对于编译器来说,很难知道运行时的实际对象,因此它只检查引用类型,而与要指向的对象无关。

Re:“当jvm决定执行哪个函数时,它只考虑引用的类型,而不考虑对象的实际类型”:更准确的说法是,编译器不会将决定推迟到jvm,因此不是jvm做出这个决定。(考虑到这一事实,应该很明显,为什么只考虑表达式的静态类型,而不考虑其值的运行时类型。)此外,当你问“为什么”时,我并不完全清楚你在问什么“。您是否要求提供指向Java语言规范中指定这一部分的链接?您是否要求解释该语言为何以这种方式设计?您只是在口头上问“为什么?”:-PClassname应始终以大写开头,newTest和newTest1不遵循编码约定。Re:“当jvm决定执行哪个函数时,它只考虑引用的类型,而不考虑对象的实际类型”:更准确的说法是,编译器不会将决定推迟到jvm,因此不是jvm做出这个决定。(考虑到这一事实,应该很明显,为什么只考虑表达式的静态类型,而不考虑其值的运行时类型。)此外,当你问“为什么”时,我并不完全清楚你在问什么“。您是否要求提供指向Java语言规范中指定这一部分的链接?您是否要求解释语言为何以这种方式设计?您是否只是在口头上问“为什么”?:-PClassname应始终以大写开头,newTest和newTest1不遵循编码约定。这种解释没有意义。“对于编译器来说,很难知道运行时的实际对象…”。事实上,编译器不可能知道这一点。但它可以由Java运行时系统处理。事实上,在其他一些语言中,它可能是在运行时处理的。是的,我们可以说不可能,但通过一些高级逻辑,可能知道实际对象(不确定如何处理),我相信没有什么是不可能的概念。“高逻辑”是不够的。Java编译器无法对尚未编写的类的行为进行推断。这种解释没有意义。“对于编译器来说,很难知道运行时的实际对象…”。事实上,编译器不可能知道这一点。但它可以由Java运行时系统处理。事实上,在其他一些语言中,它可能是在运行时处理的。是的,我们可以说不可能,但通过一些高级逻辑,可能知道实际对象(不确定如何处理),我相信没有什么是不可能的。“高逻辑”是不够的。Java编译器不能对尚未编写的类的行为进行演绎。