日期:2014-05-20  浏览次数:20660 次

内存分配问题
Java code

package pack;

public class Aaa {

    public static void main(String[] args) 
    {
        Father f=new Child();
        f.print();
        //f.print2();//编译报错
    }

}
class Father
{
    int a=9;
    public void print()
    {
        System.out.println(a);
    }
}
class Child extends Father
{
    int a=10;
    public void print()
    {
        System.out.println(a);
    }
    public void print2()
    {
        System.out.println("print2");
    }
}



求助!
有哪位大神可以帮我分析一下Father f=new Child();这条代码在JVM中的内存分配情况呀?越详细越好,希望能提及类加载时栈区,堆区和方法区的分配,及变量f的指向,如果能画图里帮我分析一下就更好了,拜托各位大神了!

------解决方案--------------------
print2();方法是子类特有的东西,通过父类的引用来调用时要把f强制转换为子类类型。只会这些你说的其他的就等高手来解决
------解决方案--------------------
1、这段代码有继承;
2、有重写;
3、有父类引用指向子类对象
属于多态,Father f=new Child();这句话的内存应该不用我画出来了吧 ?栈内存里的一小块内存指向堆内存里的一大块内存,此时f只能看到子类对象父类里的东西,但是你new出了一个child,所以f就会调用你实际对象的方法,int a=10;
public void print()
{
System.out.println(a);
}
 所以a=10;
------解决方案--------------------
和内存分配关系不大吧。主要Father f=new Child() 是父类引用指向子类对象,这个是在编译器执行的。在编译期它是作为父类的对象,因为父类没有print2()方法,所以编译器报错。但是调用哪个方法在编译器是不能确定的,这个要在运行期动态的选择,所以在运行期f.print()方法会动态去调用子类方法。 大概原理就这样吧,主要是编译期和运行期的问题吧。
------解决方案--------------------
这其实就是多态问题,父类的引用指向子类的对象,并且子类重写了父类的方法print()。在这儿父类的引用指向子类的对象,体现了强制类型转换,但是通过父类的引用调用子类的方法时,这个方法必须是子类重写的父类方法,否则就会报错
------解决方案--------------------
探讨

和内存分配关系不大吧。主要Father f=new Child() 是父类引用指向子类对象,这个是在编译器执行的。在编译期它是作为父类的对象,因为父类没有print2()方法,所以编译器报错。但是调用哪个方法在编译器是不能确定的,这个要在运行期动态的选择,所以在运行期f.print()方法会动态去调用子类方法。 大概原理就这样吧,主要是编译期和运行期的问题吧。