在 Java 中初始化最终字段

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14904771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 17:47:58  来源:igfitidea点击:

Initializing final fields in Java

java

提问by Brian Gordon

I have a class with lots of final members which can be instantiated using one of two constructors. The constructors share some code, which is stored in a third constructor.

我有一个包含许多最终成员的类,可以使用两个构造函数之一来实例化它们。构造函数共享一些代码,这些代码存储在第三个构造函数中。

// SubTypeOne and SubTypeTwo both extend SuperType

public class MyClass {
    private final SomeType one;
    private final SuperType two;


    private MyClass(SomeType commonArg) {
        one = commonArg;
    }

    public MyClass(SomeType commonArg, int intIn) {
        this(commonArg);

        two = new SubTypeOne(intIn);
    }

    public MyClass(SomeType commonArg, String stringIn) {
        this(commonArg);

        two = new SubTypeTwo(stringIn);
    }

The problem is that this code doesn't compile: Variable 'two' might not have been initialized.Someone could possibly call the first constructor from inside MyClass, and then the new object would have no "two" field set.

问题是这段代码无法编译:Variable 'two' might not have been initialized.有人可能会从 MyClass 内部调用第一个构造函数,然后新对象将没有“两个”字段集。

So what is the preferred way to share code between constructors in this case? Normally I would use a helper method, but the shared code has to be able to set final variables, which can only be done from a constructor.

那么在这种情况下,在构造函数之间共享代码的首选方式是什么?通常我会使用辅助方法,但共享代码必须能够设置最终变量,这只能通过构造函数来完成。

回答by Richard Taylor

How about this? (Updated for changed question)

这个怎么样?(更新已更改的问题)

public class MyClass {

    private final SomeType one;
    private final SuperType two;

    public MyClass (SomeType commonArg, int intIn) {
        this(commonArg, new SubTypeOne(intIn));
    }

    public MyClass (SomeType commonArg, String stringIn) {
        this(commonArg, new SubTypeTwo(stringIn));
    }

    private MyClass (SomeType commonArg, SuperType twoIn) {
        one = commonArg;
        two = twoIn;
    }
}

回答by scaevity

You need to make sure that in every constructor you are initializing all final variables. What I would do is have one constructor that initializes all the variables and have all the other constructor call that, passing in nullor some default value if there is a field that they are not given a value for.

您需要确保在每个构造函数中初始化所有最终变量。我会做的是让一个构造函数初始化所有变量,并让所有其他构造函数调用它,null如果有一个字段没有为其赋值,则传入或一些默认值。

Example:

例子:

public class MyClass {
    private final SomeType one;
    private final SuperType two;

    //constructor that initializes all variables
    public MyClas(SomeType _one, SuperType _two) {
        one = _one;
        two = _two;
    }

    private MyClass(SomeType _one) {
        this(_one, null);
    }

    public MyClass(SomeType _one, SubTypeOne _two) {
        this(_one, _two);
    }

    public MyClass(SomeType _one, SubTypeTwo _two) {
        this(_one, _two);
    }
}

回答by Halogen

All you need to do is ensure that "two" gets initialized. In the first constructor, just add:

您需要做的就是确保“两个”被初始化。在第一个构造函数中,只需添加:

two = null;

unless there's some other value you'd like to give it in the event that only the first constructor is called.

除非在只调用第一个构造函数的情况下,您想给它一些其他值。

回答by fastcodejava

You get this error because if you had called MyClass(SomeType oneIn), twois not initialized.

您会收到此错误,因为如果您调用了MyClass(SomeType oneIn)two则未初始化。