【问题标题】:Behavior of method overloading in java [duplicate]java中方法重载的行为[重复]
【发布时间】:2013-08-16 04:48:23
【问题描述】:

我尝试了以下代码

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 语言规范 中指定此内容的部分的链接?您是否要求解释为什么以这种方式设计语言?你只是在口头上问“为什么”吗? :-P
  • 类名应始终以 CAPS 开头,newTest 和 newTest1 不遵循编码约定。

标签: java polymorphism overloading


【解决方案1】:

函数重载是编译时多态性,在这里编译器决定调用哪个版本的方法。对于编译器来说,很难知道运行时的实际对象,所以它只检查引用类型,而不考虑它要处理的对象点。

【讨论】:

  • 这个解释没有意义。 “对于编译器来说,很难知道运行时的实际对象......”。实际上,编译器不可能知道这一点。但它可以由 Java 运行时系统处理。事实上,在其他一些语言中,它可能是在运行时处理的。
  • 是的,我们可以说不可能,但是通过一些高逻辑,可能知道实际的对象(不确定如何),我相信没有什么是不可能的概念。
  • “高逻辑”是不够的。 Java 编译器不能进行涉及尚未编写的类的行为的推论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-18
  • 1970-01-01
相关资源
最近更新 更多