【问题标题】:How is the memory management in polymorphism?多态性中的内存管理如何?
【发布时间】:2017-05-12 05:56:34
【问题描述】:

这样的东西如何保存在内存中(如堆栈、堆等)?

public class Animal {
    // Stuff
}

public class Dog extends Animal {
    // Stuff
}

public class Test {
    public static void main(String[] args) {
        Animal bello = new Dog();
    }
}

这是怎么回事:Animal bello = new Dog();记忆中管理? 当belloAnimal 类型的引用但它指向的对象是Dog 类型时,如何将其保存在内存中

【问题讨论】:

  • 不完全确定你在问什么。 reference bello 进入堆栈,因为它位于 main 的本地。 Dog 本身在堆上,因为您使用 new 创建它。但这对于所有对象和引用它们的所有局部变量都是一样的。继承没有区别。
  • @DavidWallace 但如果引用的数据类型与对象的数据类型不同,这不会有什么不同吗?
  • 没有。对象知道自己的class,但不知道引用它的变量的类型。
  • @DavidWallace 啊好吧,如果引用类型也是 Dog,对象 itef 也没有区别?
  • 正确。 DogDog,无论有哪些变量引用它,以及这些变量的类型是 DogAnimal 还是 Object

标签: java oop inheritance memory-management polymorphism


【解决方案1】:

Parent(base) class 将指向它的 Child 扩展它, 并从子实现它的方式分配其父属性和方法实现

   //parent class
   public class Animal {
        int x = 5;
        int y = 5;
        void fun() { return "from Animal";}
    }

   //child class
    public class Dog extends Animal {
        //constructor
        Dog( ) {   x++; }

        @override
        void fun() { return "from Dog";}
    }
    
    public class Test {
        public static void main(String[] args) {
            Animal bello = new Dog();

            bello.fun(); //return "from Dog"
            bello.x ; //6
            bello.y ; //5
        }
}

我希望这张图能很好地解释它

【讨论】:

    【解决方案2】:

    Java 将类定义为引用类型。 Java specifications 解释了这是如何工作的:

    4.3.1 对象
    对象是类实例或数组。
    引用值(通常只是引用)是指针 到这些对象,以及一个特殊的空引用,它指的是没有 对象。

    语言完全隐藏了这个实现细节,但是引用是一个传递的值(作为参数或作为堆栈上的局部变量,或作为堆中的对象字段)并允许在内存中找到真实的对象(在堆中)。所以当你写的时候:

        Animal bello = new Dog();
    

    JVM 将在堆内存中分配一个Dog 对象,new 将返回引用以找到它。赋值只是将引用复制到bello 局部变量中(编译器当然会检查类型是否兼容)。

    诀窍在于对象布局。为简单起见,对象会跟踪其真实类。编译器将生成一个精巧的布局,其中Dog 对象的布局是Animal 布局的扩展。当你调用一个方法时,对应于真实对象的类的方法就会被调用。当然,实际上,这一切都是a little more complex

    【讨论】:

    • 只是一个迂腐的吹毛求疵:“JVM 将在堆内存中分配一个 Dog 对象”——这不一定是真的。如果 JVM 能够通过静态分析确定它没有转义当前堆栈帧,则 JVM 能够在堆栈上分配 Dog 对象。见this article by Java developer Brian Goetz for more details
    • @PeriataBreatta 非常有趣的文章!谢谢 !虽然,我的意图更多是给出一个经验法则和对一般原则的理解。
    猜你喜欢
    • 2012-01-10
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多