当前位置: 首页 > 面试题库 >

什么是Java中的对象字段初始化和构造函数顺序

巫马松
2023-03-14
问题内容

我今天早些时候在代码中结束了以下场景(我承认这有点怪异,并且从此以后就进行了重构)。当我运行单元测试时,我发现在超类构造函数运行时尚未设置字段初始化。我意识到我不完全了解构造函数/字段初始化的顺序,因此我希望大家能向我解释这些顺序。

class Foo extends FooBase {
    String foo = "foobar";

    @Override
    public void setup() {
        if (foo == null) {
            throw new RuntimeException("foo is null");
        }
        super.setup();
    }
}

class FooBase {
    public FooBase() {
        setup();
    }

    public void setup() {

    }
}

@Test
public void testFoo() {
    new Foo();
}

JUnit的缩写backtrace如下,我想我期望$ Foo。 设置foo。

$Foo.setup
$FooBase.<init>
$Foo.<init>
.testFoo

问题答案:

是的,在Java中(例如,与C#不同) 在超类构造函数 之后 调用字段初始化器。这意味着在执行字段初始化程序 之前
,将调用构造函数的所有重写方法。

顺序为:

  • 初始化超类(递归调用这些步骤)
  • 执行字段初始化
  • 执行构造函数主体(在任何构造函数链接之后,该过程已在步骤1中进行)

基本上,在构造函数中调用非最终方法是个坏主意。如果要这样做,请 非常
清楚地记录下来,以便任何重写该方法的人都知道在执行字段初始化程序(或构造函数主体)之前将调用该方法。

有关更多详细信息,请参见JLS
12.5节



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

  • 问题内容: 如果未将ArrayList初始化为字段,则将项目添加到ArrayList时出现NullPointerException。谁能解释为什么? 当我将ArrayList初始化为字段时起作用: 当我将ArrayList声明为字段然后在Class构造函数中对其进行初始化时,它不起作用: 问题答案: 因为构造函数中的版本正在创建一个新变量,而该变量恰好与您的成员字段名称相同,而成员字段仍未设置。这

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

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

  • 问题内容: 我最近一直在用C#和Java进行编程,并且很好奇初始化我的类字段的最佳位置。 我应该在申报时这样做吗: 还是在构造函数中?: 我真的很好奇你们中的一些资深人士认为这是最佳做法。我要保持一致,并坚持一种方法。 问题答案: 我的规则: 不要在声明中的默认值初始化()。 如果你没有用于更改字段值的构造函数参数,则最好在声明中进行初始化。 如果字段的值由于构造函数参数而改变,则将初始化放入构造

  • 本文向大家介绍C++构造函数初始化顺序详解,包括了C++构造函数初始化顺序详解的使用技巧和注意事项,需要的朋友参考一下 1.构造函数、析构函数与拷贝构造函数介绍 构造函数 1.构造函数不能有返回值 2.缺省构造函数时,系统将自动调用该缺省构造函数初始化对象,缺省构造函数会将所有数据成员都初始化为零或空 3.创建一个对象时,系统自动调用构造函数 析构函数 1.析构函数没有参数,也没有返回值。不能重载