1. 引言

Java开发者对于在声明时还是在构造函数中初始化变量持有不确定性。本文将探讨在声明或构造函数中初始化变量会发生什么,并指出它们之间的异同。

2. 字段声明初始化

我们需要知道,Java编译器会移除所有字段声明时的初始化,并按照它们在类中出现的顺序作为代码添加到构造函数中。因此,我们可以推断在声明和构造函数中初始化变量没有太大区别,因为最终它们都会被编译到构造函数中:

public class A {
    private B b = new B();
}

3. 构造函数字段初始化

从上面的代码来看,经过编译后,我们得到这样的构造函数:

public class A {
    private B b;

    public A() {
        this.b = new B();
    }
}

那么在哪里初始化数据真的重要吗?

了解了编译后的结果后,其实差别不大。更多的是根据我们的经验和偏好来决定。

4. 指南

在决定在字段声明还是构造函数中初始化数据时,可以参考一些准则

这是依赖注入构造函数的例子:

public A(B b) {
    this.b = b;
}

推荐的初始化变量方式是使用依赖注入。这种方式有助于遵循不同的原则。

4.1. 可读性

为了提高可读性,我们可能希望在字段声明或构造函数中初始化数据,但不两者兼有。当然,这只是一个指导原则,而不是硬性规定,因为可以在两者之间都进行初始化。

所有初始化代码放在一个地方,便于查找,使得未来开发者更容易在一个地方查看初始化代码,而不是分散在多个位置。

4.2. 单一职责原则

通过使用依赖注入构造函数,我们将创建 B 对象的责任从 A 类中移除。遵循单一职责原则始终是首选。

这也意味着我们能降低类之间的耦合度,这是另一个值得遵循的优秀准则。

4.3. 测试性

使用这种构造函数通常使得测试代码更加容易,因为我们可以轻松地模拟 B 对象,并通过构造函数将其注入到 A 对象中:

B b = mock(B.class);
A a = new A(b);

4.4. 维护性

低耦合的类也带来了更好的代码维护性,使我们能够更轻松地修改代码。

5. 总结

在这篇文章中,我们了解到在字段声明或构造函数中初始化变量更多是一种偏好,它们之间的差异主要体现在我们想要遵循的设计原则上。

使用构造函数初始化和依赖注入可以带来设计原则的一些优势

如往常一样,示例代码的源代码可在GitHub上找到。