命名约定:最终字段(非静态)


23

今天,我与一位同事讨论了finalJava类中字段的命名。

在他的观点中,final字段也应视为常量,因为其值在创建实例后不会更改。

这将导致以下final字段命名约定:

public class Foo {
    private static final String BLA_BLA = "bla";

    private final String BAR_BATZ;

    ...
}

在我看来,只有static final字段应被视为常量,而仅字段应final遵循通常的camelCase命名约定。

public class Foo {
    private static final String BLA = "bla";

    private final String barBatz;

    ...
}

现在我有点不确定,因为他是比我经验丰富的程序员,我通常同意他的观点,并认为他是一个非常好的开发人员。

有什么意见吗?


您的示例不是常量;您在编译时尚未为其分配任何值。因此,它们不遵循常量的命名约定。
罗伯特·哈维

@RobertHarvey谢谢,你是对的。本...是为了象征任何可能的构造这台final场,但是这显然是不可能的static final领域。
2014年

1
@Zeeker您可能对在static { }加载类后可用于在类中设置静态字段的块感兴趣。相关工作在Java静态构造函数

@RobertHarvey我熟悉那些。但是还是谢谢。
2014年

1
我要说的是,由于变量属于一个实例,因此实例与实例之间会有所不同,因此它不适用于常量。我会用骆驼的情况。
Florian F

Answers:


20

Sun(现在是Oracle)维护了一个名为Java编程语言的代码约定的文档。上次更新是在99年,但风格指南的精髓仍然存在。

第9章介绍命名约定。

对于“常量”的标识符类型:

声明的类常量和ANSI常量的变量名称均应全部大写,且单词之间用下划线(_)分隔。(为避免调试,应避免使用ANSI常数。)

给出的示例:

static final int MIN_WIDTH = 4;

static final int MAX_WIDTH = 999;

static final int GET_THE_CPU = 1;

在最近的文件中-它滑入了那里。从变量(Java教程>学习Java语言>语言基础

如果您选择的名称仅包含一个单词,则用所有小写字母拼写该单词。如果它包含多个单词,请大写每个后续单词的第一个字母。名称gearRatiocurrentGear是该约定的主要示例。如果您的变量存储一个常量值(例如)static final int NUM_GEARS = 6,则约定会稍有变化,将每个字母大写并用下划线字符分隔后续单词。按照惯例,下划线字符永远不会在其他地方使用。

许多用于Java的静态分析器都试图强制执行此操作。例如,checkstyle强制执行:

检查常量名称是否符合format属性指定的格式。常量是静态和最终字段或接口/注释字段,但serialVersionUID和除外serialPersistentFields。格式为正则表达式,默认为^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$


这实际上归结为社区编写代码的惯例 ……并且理想情况下保持原样。

上面的示例作为static final可能源自C约定的示例给出#define-与C一样,它们在编译过程中而不是在运行时被替换为代码。

然后应该问的问题是“这是像常量吗?还是像一次写入字段一样?” -然后相应地遵循约定。对于这个问题的试金石将是“如果您要序列化对象,您是否要包括final字段?” 如果答案是它是一个常量,则将其视为常量(不要序列化)。另一方面,如果它是需要序列化的对象状态的一部分,则它不是常数。

无论哪种情况,重要的是要坚持代码风格,无论对错。更糟糕的问题是由项目中不一致的约定引发的,而不仅仅是惹人注目的问题。考虑获得一些静态分析工具并对其进行配置以保持一致性。



@RobertHarvey我可以设想某些情况下实例字段的行为像常量。以工厂为例,在对象中填充原本应该是常量的东西……尽管这些都是非常人为的示例,但在思考为什么要这样做的时候,却伤了我的头。

感谢您提供详细的答案。关于对象序列化的石蕊测试对我来说很重要。
2014年

一位同事最近提出了一个正确的观点,即曾几何时,编辑人员不太擅长突出静态/静态最终结果等,因此此命名约定很重要。如今,IDE相当不错,因此我们可以为它们命名更好一些,例如:MinWidth代替MIN_WIDTH。另一个问题是:静态最终记录器如何处理?您称它们为LOG/ LOGGERlog/ logger。就个人而言,log看起来更好地与代码内联,但是何时可以接受不一致(如果有)?
ndtreviv

5

BAR_BATZ在此示例中不是常数。的构造函数Foo可以在对象级别将其设置为不同的值。例如

public class Foo {
    private final String BAR_BATZ;

    Foo() {
       BAR_BATZ = "ascending";
    } 

    Foo(String barBatz) {
       BAR_BATZ = barBatz;
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.