Java中定义字符串常量的编程实践

Java中定义字符串常量的编程实践,java,string,constants,Java,String,Constants,我对在Java中定义字符串常量的看法是,当同一个字符串在多个位置使用时,应该定义一个字符串常量。这有助于减少打字错误,减少将来更改字符串等的工作量 但是在一个地方使用的字符串呢。即使在这种情况下,我们也应该声明字符串常量吗 例如,记录一些计数器(随机示例) 声明常量而不是使用原始字符串是否有优势 编译器是否进行任何优化 您可能希望为包含该行代码的任何方法编写单元测试。该单元测试需要访问该字符串值。如果不使用常量,将重复两次字符串,如果将来必须更改它,则必须在两个位置都更改它 所以最好使用常量,

我对在Java中定义字符串常量的看法是,当同一个字符串在多个位置使用时,应该定义一个字符串常量。这有助于减少打字错误,减少将来更改字符串等的工作量

但是在一个地方使用的字符串呢。即使在这种情况下,我们也应该声明字符串常量吗

例如,记录一些计数器(随机示例)

  • 声明常量而不是使用原始字符串是否有优势
  • 编译器是否进行任何优化

您可能希望为包含该行代码的任何方法编写单元测试。该单元测试需要访问该
字符串
值。如果不使用常量,将重复两次
字符串
,如果将来必须更改它,则必须在两个位置都更改它


所以最好使用常量,即使编译器不会进行任何有益的优化。

声明常量可以改进代码,因为它们更具描述性。在你的例子中

CounterLogger.addCounter("Method.Requested" , 1)
方法参数
“method.Requested”
是非常自我描述的,但是
1
没有使其成为常数,这将使该示例更具可读性

CounterLogger.addCounter("Method.Requested" , INITIAL_VALUE)

我认为你的情况很好。如果你看不出把它声明为常数有什么好处,就不要这样做。为了支持这一点,请看一看SpringJDBCTemplate(我毫不怀疑Spring代码是一个很好的例子),它充满了这样的字符串文本

Assert.notNull(psc, "PreparedStatementCreator must not be null");
Assert.notNull(action, "Callback object must not be null");
throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
但只有两个常数

private static final String RETURN_RESULT_SET_PREFIX = "#result-set-";
private static final String RETURN_UPDATE_COUNT_PREFIX = "#update-count-";
令人遗憾的是,这条线

Assert.notNull(sql, "SQL must not be null");

在代码中重复5次,但作者拒绝将其设置为常量

在我看来,字符串可以通过以下两种方式之一使用:
  • 作为属性/键/枚举-或者换句话说,作为应用程序的另一个对象/状态的内部表示,其中一个代码组件写入它们,另一个组件读取它们。
  • 在UI中-用于GUI/控制台/日志显示目的

    我认为很容易看出,在这两种情况下,避免硬编码是多么重要

    第一类字符串必须(如果可能)存储为常量,并公开给可能使用它们进行输入/输出的任何程序组件

    显示的字符串(如记录器中的字符串)是将来可能更改的字符串。将它们全部存储为常量专用类中的
    static final
    字段可以使以后的修改更加容易,并有助于避免类似消息的重复


    关于优化问题-正如其他人已经回答的那样,我相信没有显著的区别。

    否,和否….JVM将组合字符串文字池中使用的所有字符串文字,无论字符串文字出现多少类或JAR。否,和否。。。除了国际化,如果您将字符串定义为常量(可能在单独的类中,或者将它们存储在特殊的文件中),那么查找和编辑它们会更容易。有时会容易得多。虽然我觉得离题是值得注意的。我不同意。如果字符串常量是被测试方法的参数,那么单元测试应该只知道要使用的字符串常量。在这种情况下,单元测试需要明确使用什么字符串值。如果有人转到实现类并更改常量,测试将中断,并迫使开发人员对其进行检查和更新,以确认该类的接口现在正在更改。
    Assert.notNull(sql, "SQL must not be null");