构造函数和属性中的final

时间:2019-06-04 22:01:14

标签: java

我有一个final属性和一个构造函数:

public abstract class AbstractTest<T> {

    protected final T test;

    // no need for final, as property is already declared as final?
    protected AbstractTest(final T test) {
        this.test = test;
    }

}

我应该将final放在属性和构造函数上,还是将final从构造函数中删除?

4 个答案:

答案 0 :(得分:4)

protected AbstractTest(final T test) {
    this.test = test;
}

标记函数参数final可以防止您在函数内部修改变量。它根本不影响调用者,也不影响类的任何其他部分。外部代码不会在乎任何一种方式。它仅在函数实现内部相关。

protected AbstractTest(final T test) {
    this.test = test;
    test = null;       // Illegal if the parameter is final, legal otherwise.
}

由您决定是否将参数标记为最终值。

如果您想知道this.test是否为final意味着test参数也应该为final:。一个与另一个无关。您可以将两个变量都标记为final,既不是final,也可以标记为final,而不是另一个。

如果您仍然不确定该怎么做,我的建议是:不要将参数标记为final。这是额外的输入,几乎没有带来什么好处。

答案 1 :(得分:1)

'final'是变量的属性,而不是引用的对象。

之后:

protected AbstractTest(final T test) {
    this.test = test;
}

您仍然可以修改this.test引用的对象:

this.test.something = 42;

(假设适当的访问权限;但是将this.test声明为final T test并不会阻止您)。

应用于构造函数参数的“最终”仅可防止您分配给构造函数参数“ test”。由于您仍然不想这样做,因此没有任何区别。即使您确实分配了“测试”,例如:

   this.test = test;
   test = null;

呼叫者可以看到的没有区别;您正在更改参数变量的本地副本,而不是它指向的对象。

因此,“最终”是多余的。

答案 2 :(得分:1)

您有2个不同的变量:字段和参数。

在两种情况下,final表示变量在初始分配后不能更改。

由于参数是在调用方法/构造函数时分配的,因此它永远无法更改。通常这是一件好事,因为更改参数的值可能会造成混淆。

无论如何,这2个变量是它们自己的变量,因此2个final修饰符是完全独立的,因此应该将它们都保留。

就我个人而言,我从未将final放在参数上。相反,如果尝试更改该值,则会打开编译器警告。这样,我就没有多余的关键字,但这只是我的编码风格。指定final意味着编译器将总是失败,而不仅仅是警告它,并且不会由于错误而遗漏或压抑,因此您可以选择该编译器。

答案 3 :(得分:0)

在Java变量中使用final表示在接收到值后它将保持不变。

当您将变量声明为常量时,您无需在

中出现它时就将final结尾
protected AbstractTest(final T test)

只放

protected AbstractTest(T test)