1

对于以下代码:

class Parent {
    public void say(){
        System.out.println("Parent");
    }
}

class Child extends Parent{
    public void say(){
        System.out.println("Parent");
    }
}

class Test {
    public static void main(String[] args){

        Parent p = new Child(); // What does the compiler check  
        p.say();
    }
}

以下问题一直困扰着我。

1. 编译期间究竟发生了什么?编译器如何知道 Parent p = new Child() 是有效代码,因为在编译时没有创建任何对象?

2. 运行时到底发生了什么?内存是如何分配的

3. 对父构造函数的隐式调用创建了一个父对象。还创建了一个子对象。它是如何存储的以及 jvm 如何将其用于方法解析。

4. 最后,是 JVM 硬编码不覆盖静态方法和变量还是有其他原因。为什么我们不能使用运行时对象实例方法()为什么不使用运行时对象变量

我可以在哪里阅读有关这些主题的更多信息?

谢谢

4

1 回答 1

3

exactly is happening during compile time? How does the comiler know that Parent p = new Child() is a valid code as no object has been created at compile time?

Well, whole books are written about that subject. In essence, the compiler parses the input source, and it finds that assignment:

Parent p = new Child(); 

And now the compiler does two things:

  • it checks what it can find out about the types on both sides of the assignment
  • thus it finds: the left hand side needs an object of type `Parent``
  • it also looks at the right hand side, to understand the (potential) result types that comes out of that expression

So, in the end, the compiler will see: "I need a Parent ... and I get something that is a Child." Then the compiler has to check if an instance of Child satisfies "I need a Parent". And obviously: it does.

what exactly is happening at runtime? How is memory allocated

Again, whole books are written about that. See here for example.

The implicit call to parent's constructor creates an Parent Object. A child object is also created. How is it stored and how does jvm use this for method resolution.

The JVM "simply" knows two things:

  • when reserving the memory for a Child object, it needs to also consider the memory required for any super class fields
  • so, in the end, you simply have one area of memories large enough to hold all fields of all parent classes, down to the Child class itself

Finally: static methods are inherented, but yes, there is no polymorphism for them in Java. That is simply a design point of the language, and the semantics that are defined for Java. It could be done differently, but 20+ ago, the fathers of Java decided to do it like they did.

于 2019-07-01T05:07:20.063 回答