简体   繁体   English

如何初始化一个类字段?

[英]how to initialize a class field?

I have seen developers initialize their class fields in different ways. 我已经看到开发人员以不同的方式初始化其类字段。 Three of them are very popular! 其中三个很受欢迎! What's the difference and is any of them more proper? 有什么区别,它们中的任何一个是否更合适?

class Test {
    ArrayList<String> myArr = new ArrayList<String>(); // First Method 
}


class Test {
    ArrayList<String> myArr;
    public Test() {
        myArr = new ArrayList<String>(); // Second Method
    }
}


class Test {
    ArrayList<String> myArr;
    public Test() {
    }
    public void Init() {
        myArr = new ArrayList<String>(); // Third Method
    }
}

1 and 2 are more-or-less equivalent and also allow you to use the final modifier on the field. 1和2大致等效,还允许您在字段上使用final修饰符。

(The difference is that in case 1, the field is initialized before constructor invocation, whereas in case 2, the field is initialized when the constructor is invoked.) (不同之处在于,在第一种情况下,该字段在构造函数调用之前被初始化,而在第二种情况下,该字段在构造函数被调用时被初始化。)

3 is a lazy initialization pattern. 图3是一个懒惰的初始化模式。

There are not much differences between the first and the second: the difference is more syntactic. 第一个和第二个之间没有太多区别:区别在语法上更强。

In the first approach you place the declaration and the defintion together, so you won't forget to initialze the variable. 在第一种方法中,将声明和定义放在一起,这样就不会忘记初始化变量。

The second and thrid approaches allow more flexibility if you want to initialize differently based on some conditions. 如果要根据某些条件进行不同的初始化,则第二种方法和第三种方法可以提供更大的灵活性。

The third is more for frameworks where you have to have a parameterless constructor and will call the "real" initializer method (With all the necessary parameters) separately. 第三个是针对必须具有无参数构造函数的框架的,它们将分别调用“实际”初始化方法(带有所有必需的参数)。 The third approach also allows easier "reset" of the object to its initial state. 第三种方法还允许将对象更容易地“重置”为其初始状态。

Note : if you have a final field, you can only use the first or second approach, as it cannot be re-assigned once the intial assignment takes place and that assignment has to happen by the end of the constructor 注意 :如果您有一个final字段,则只能使用第一种或第二种方法,因为一旦发生初始分配并且该分配必须在构造函数的末尾进行,则无法重新分配它

1 and 2 are equivalent but if variable is static then behavior differs like below code 1和2是等效的,但如果变量是静态的,则行为会有所不同,例如以下代码

public class Test {
static String s="2"; // 1

Test()
{
    System.out.println(s);
    s="3"; //2
}

public static void main(String[] args) throws IOException {

    System.out.println("1="+s);
    new Test();
    System.out.println("1="+s); 
 }

In 1 initialization happens when class loads but if you initialize static variable in constructor (2) then value will be assigned when object is constructed. 在1中,初始化发生在类加载时,但是如果在构造函数(2)中初始化静态变量,则在构造对象时将分配值。

3) On demand you are initializing variable. 3)根据需要,您正在初始化变量。

class Test {
ArrayList<String> myArr;
public Test() {
}
public void Init() {
    myArr = new ArrayList<String>(); // Third Method
}
}

It's about control and readability : 关于控制和可读性:

the first and the second are equivalent. 第一个和第二个是等效的。

the second help you control the order of the initializations. 第二个帮助您控制初始化的顺序。

the third can offer delay (lazy init) like if you test your class and don't want to create everything. 第三个可以提供延迟(惰性init),例如,如果您测试类并且不想创建所有内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM