由于在java中继承而创建了多少对象? [英] How many objects are created due to inheritance in java?

查看:142
本文介绍了由于在java中继承而创建了多少对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有三个类:

class A {
    A() {
        // super(); 
        System.out.println("class A");
    }
}
class B extends A {
    B() {
        // super(); 
        System.out.println("class B");
    }
}
class C extends B {
    public static void main(String args[]) {
        C c = new C(); //Parent constructor will get called
    }
}

类C的实例,它调用超类的构造函数。那么,是否有多个对象被创建?如果只创建一个对象,那么super()如何像另一个类的构造函数? super()方法在内部创建一个对象吗?我知道的是,构造函数也是一个方法(我可能是错误的)。

When I create an instance of class C, it calls the constructor of super class. So, is there more than one object that is getting created? If only one object is created, then how is super() like another class' constructor? Does super() method internally create an object? What I know is, the constructor is also a method (I may be wrong).

我的问题是: >


  1. 在这种情况下创建多少个Object?

  2. 如果创建了一个对象那么Super()如何在内部调用父类构造函数?


推荐答案

您正在探索的是Java 初始化对象 - 并且涉及到很多步骤。

Great question. What you are probing is how Java initializes objects - and there are a number of steps involved.


是构造函数也是一个方法(也许我错了)。

i know is constructor is also a method (Maybe i am wrong).

接近正确。构造函数是一种特殊的方法。如果反编译类文件,您将看到构造函数重命名为< init> < init> 与其他方法的处理方式不同,例如,除非通过使用关键字 new super 。这是非常根本的,它是在JVM本身实现的,而不是在Java语言中定义的东西。

Nearly right. The Constructor is a special method. If you decompile a class file, you'll see the constructors get renamed to <init>. <init> is treated differently from other methods and, for example, can't be called explicitly except through use of the keyword new or super. This is so fundamental that it is implemented in the JVM itself rather than being something defined in the Java language.


Object的数量是多少

How many number of Object is created in this case.

创建一个对象 - C

One object is created - an instance of C.

C B 的实例,以及 A Object 的实例。

C is additionally and simultaneously an instance of B and an instance of A and also Object.


如果创建一个对象,然后内部 super()是否调用父类构造函数。如何Super调用父类构造函数。

If one object is created then how internally super() is calling Parent class Constructor . How Super is able to call parent class constructor.

这是我们进入初始化 - 初始化是如何JVM创建一个新的实例,并设置所有成员值 - 特定类和超类的成员值。涉及到几个阶段:

This is where we get into initialization - initialization is how the JVM creates a new instance of an object and sets all the member values - those of the specific class and those of the superclasses. There are several stages involved:


  • 加载所有引用的类并初始化这些类。类初始化本身是不平凡的,所以我不会在这里覆盖。

  • 分配一块内存用于保存实例的成员,其中包括 A B C 注意这解释了您的问题的一个方面:基类的构造函数及其子类如何更新或引用同一对象 - 所有类的实例的所有成员都存储一个在另一个之后在同一块内存中。

  • 将所有成员初始化为其默认值。例如, int float 成员将设置为0和0.0f。

  • 执行或计算成员初始值设定,例如:

  • Load all the referenced classes and initialize those classes. Class initialization is itself non-trivial so I won't cover it here. It is well worth reading up.
  • Allocate a chunk of memory for holding the members of the instance, which will include the all members of A, B and C. NOTE this explains one aspect of your question: how can the constructors of the base class and its subclasses update or refer to the same object - all the members of the instance from all classes are stored one after the other in the same chunk of memory.
  • Initialize all the members to their default value. For example, int and float members will be set to 0 and 0.0f.
  • Execute or calculate the member initializers, eg:

private int a = 10;
private int b = a * 5;
private String c = Singleton.getInstance().getValue();


  • 注意(1)成员初始化严格按照成员在类。这意味着在声明后面的成员引用被破坏:

  • Note (1) that member initialization occurs strictly in the order that members are declared in the class. This means that references to members later in the declaration are broken:

    private int a = b * 5; // Forward reference; won't compile
    private int b = 10;
    


  • 注意(2)Java中有一个未充分利用的工具,以在之前初始化值。这些代码块在此时再次严格按照声明的顺序执行:

  • Note (2) that there is a under-used facility in Java to run arbitrary code to initialize values before the constructor is executed. These code blocks are executed at this time again strictly in order of declaration:

    private int a;
    private int b = 1;
    {
        // Initization occurs after b but before c.
        // c cannot be referenced here at all
        int i = SomeClass.getSomeStatic();
        a = i * 2;
    }
    private int c = 99;
    


  • 执行 C 。构造函数必须直接从超类调用构造函数,否则编译器会自动添加 super()作为构造函数的第一行。这意味着构造函数按顺序严格执行:

  • Execute the constructor of C. Constructors must either directly invoke a constructor from the superclass or the compiler will automatically add super() as the first line of the constructor. This means that the constructors are strictly executed in order:


    1. 对象

    2. A

    3. B

    4. C

    1. Object
    2. A
    3. B
    4. C


  • 对象现在已经初始化,可以使用了。如果使用实例方法初始化值,则可以执行一些危险的操作:

    The object is now initialized and is ready for use. You can do some dangerous stuff if you initialize value using instance methods:

    public class Wrong {
        int a = getB(); // Don't do this!
        int b = 10;
        public int getB() {
             return b;
        }
    }
    

    这里, code>初始化为 0 。这是因为,在调用 getB()时,Java已将 b 的值清除为默认值 0 ),但尚未在初始化的第二阶段将其设置为 10

    Here, a is initialized to 0. This is because, at the point getB() is invoked, Java has cleared the value of b to the default (0), but has not yet set it to 10 in the second phase of initialization.

    总而言之,只有一个对象,它在一个数字中分阶段创建和初始化。在这些阶段,根据定义,对象未被完全定义。

    In summary - there is only one object and it is created and initialized in a number in stages. During those stages, the object is, by definition, not completely defined.

    这篇关于由于在java中继承而创建了多少对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆