现场变量最终是否需要吸气剂?

Lud*_*wig 11 java conventions

在Java中,它是常规(据我所知)将您的字段变量保密并使用getter和/或setter访问它们.这样您就可以设置更改变量值的规则.

但如果变量是最终的呢?例:

public class Test {

    public final int MY_INT;

    public Test(int myInt) {
        MY_INT = myInt;
    }

}
Run Code Online (Sandbox Code Playgroud)

这会被允许吗?它编译和工作正常,但它被认为是好的代码?

Sto*_*ica 16

这编译但它不被认为是好的代码.

MY_INT违反命名约定:用全部大写的名字被用于static final变量,也被称为"类常量"(见这个这个,谷歌的Java风格指南太).要符合命名约定,最好重命名为myInt.

建议使用getter来隐藏类的实现细节.接口只包含方法,而不包含字段.如果您让其他类按名称引用此字段,则您将无法在以后更改名称或内部表示.

但最重要的是,子类不能覆盖字段,它们只能覆盖方法.如果您提供getter而不是字段,则子类将能够覆盖它并实现不同的行为.因此,提供一个getter并禁止直接访问该字段本身会更好.

(感谢@Sotirios Delimanolis的编码风格指南链接,非常感谢!)

  • 我认为在这个SE网站上解释了最合适的答案:http://programmers.stackexchange.com/questions/252243/naming-convention-final-fields-not-static (3认同)

nma*_*rko 5

如果客户端可以在分配值之前访问问题中的公共字段(即,不调用构造函数),那么就会出现一个明显的问题。具体来说,当客户端尝试访问该字段时,该字段无法具有预期/正确的值。尽管如此,正如注释中所指出的,您尚未Test.MY_INT使用static标识符进行声明,因此在不首先调用构造函数的情况下基本上不可能检索该常量的值。

因此,做你正在做的事情似乎是明智的(就不变性而言)。然而,就“好的代码”而言,您(正如其他人所说)强迫自己和您的客户通过名称明确引用该值。但是,如果您使用 getter,并且需要更改 的名称,MY_INT同时保持常量的目的相同,那么您和您的客户都不会被迫更改 中实现之外的任何内容Test

更明确地说,我为您的类提供了 getter 和私有化常量。

public class Test {

    private final int MY_INT;

    public Test(int myInt) {
        MY_INT = myInt;
    }

    public int getAssignedIntValue() {
        return MY_INT;
    }

}
Run Code Online (Sandbox Code Playgroud)

我会得到分配的整数值,如下所示:

Test test = new Test(1);
// with your class
test.MY_INT;
// with the above class    
test.getAssignedIntValue();
Run Code Online (Sandbox Code Playgroud)

现在,假设我重命名MY_INTmyInt以匹配命名约定。在这两种情况下,我都必须更改类MY_INT中所有出现的Test。但是,当我需要使用新常量名称获取值时,两种实现之间的差异就变得很明显:

// if this is the old code from above
Test test = new Test(1);
// I need to change this to test.myInt, or I get an ERROR!
test.MY_INT;
// since I didn't change the name of the getter, all is well
test.getAssignedIntValue();
Run Code Online (Sandbox Code Playgroud)

注意:虽然这可能是一个可以接受的答案,但它不一定具有最适用的推理。请参阅此答案以了解在更一般的背景下给出的推理。

  • 如果没有实例,他们将很快无法访问它。 (3认同)
  • 没有。它甚至不会出现在 IDE 自动建议中。 (2认同)

hfo*_*nez 5

提供者的答案不完整(甚至选择了一个作为“答案”的答案)。请考虑如果所讨论的字段是一个Collection或对象数组会发生什么。将所有字段设为私有并为这些字段提供“获取程序”是一个好习惯。但更具体地说,您的getter应该返回对该字段(即String)的(不可变的)引用,或返回可变字段(即对象数组)的防御性副本。这是因为,即使您无法更改所讨论对象的基地址,也可以通过简单地获取基地址来更改对象的内部(数组或集合)。请记住,通过可变字段,我不仅指数组或集合。它适用于任何可变类。

让我们回到正题,在干将REQUIRED?答案是不。 但是,如果您想拥有健壮的代码,那么遵循这些最佳实践将是您的最大利益;即使只是养成良好的习惯。除非您定期进行练习,否则您在编写代码时将不会遵循良好的做法(而且项目中的其他人也可能不会这样做)。