当前位置: 首页 > 知识库问答 >
问题:

关于Java构造函数和类成员初始化的问题[duplicate]

夏华藏
2023-03-14

我试图理解为什么以下Java代码的输出是这样的:

class A {
    public A() {
        System.out.print("A()");
    }
    public static void main(String[] args) {

    }
}
class B {
    public B() {
        System.out.print("B()");
    }

    public static void main(String[] args) {}
}
class C extends A {
    B b = new B();
}

public class E05SimpleInheritance {
    public static void main(String args[]) {
        new C();
    }
}

输出:

"A()B()"

我可以想象,当E05SimpleInheritance公共类的主要方法被调用时,应该会发生以下事情

  1. 加载非公共类C并初始化其字段(在调用类C的默认构造函数之前)

所以最终的输出应该是B()A(),这显然是错误的,所以我不太明白在这种情况下代码是如何流动的。你能告诉我为什么打印的是A()B()而不是B()A()吗

共有1个答案

冯霖
2023-03-14

你的错误在步骤1:

加载非公共类C并初始化其字段(在调用类C的默认构造函数之前)

事情不是这样的。实际上,非静态字段是在构造函数的开头初始化的,而不是在它之前。甚至在此之前,基类构造函数也被隐式(或显式)调用。

换句话说,javacC生成代码,相当于以下内容:

class C extends A {
    B b;

    C() {
        super();
        b = new B();
    }
}
 类似资料:
  • 本文向大家介绍关于C++类的成员初始化列表的相关问题,包括了关于C++类的成员初始化列表的相关问题的使用技巧和注意事项,需要的朋友参考一下 在以下四中情况下,要想让程序顺利编译,必须使用成员初始化列表(member initialization list): 1,初始化一个引用成员(reference member); 2,初始化一个常量对象(const member); 3,调用一个基类的构造函

  • 本文向大家介绍浅谈c++构造函数问题,初始化和赋值问题,包括了浅谈c++构造函数问题,初始化和赋值问题的使用技巧和注意事项,需要的朋友参考一下 默认构造函数(就是没有参数的构造函数) The Default Constructor The default constructor is the constructor used to create an object when you don't p

  • 映射对构造函数没有限制或要求 (__init__ )类的方法。您可以自由地为您想要的函数要求任何参数,为ORM未知的实例分配属性,并且通常在编写Python类的构造函数时做您通常会做的任何其他事情。 sqlAlchemy ORM不调用 __init__ 从数据库行重新创建对象时。ORM的过程有点类似于Python标准库的 pickle 模块,调用低级 __new__ 方法,然后在实例上悄悄地恢复属

  • 生成类对象时,其成员可以用类的构造函数初始化。构造函数是与类同名的成员函数。程序员提供的构造函数在每次生成类对象(实例化)时自动调用。构造函数可以重载.提供初始化类对象的不同方法。数据成员应在类的构造函数中初始化或在生成对象之后设置其数值。 常见编程错误 6.7 类的数据成员只能在类定义中初始化。 常见编程错误 6.8 试图声明构造函数的返回类型和返回植是个语法错误。 编程技巧 6.5 适当时候(

  • 这是一个关于java中子类的非常基本的问题,我还是不明白…… 假设我有一个超类,它有三个字段,并且只有默认的构造函数: 我想添加一个字段x。我无法更改,所以我创建了一个子类: 我现在想从现有的对象生成object: 这样我仍然可以访问,等。 如果不在子类的构造函数中“手动”分配所有这些字段,我如何才能最好地做到这一点?

  • 本质上,我想要一个具有数组的模板类,其大小是一个模板参数,以保存常量内容。 类似于: 我一直在搜索和修补一点,几乎有一个解决方法实现了一个中间静态方法,并使用std::array: ...这已经是相当多的样板,但仍然d::array似乎不是从初始化列表中构建的?:-(