【问题标题】:Should we keep symbols/special characters in StringConstants file?我们应该在 StringConstants 文件中保留符号/特殊字符吗?
【发布时间】:2014-04-24 14:43:34
【问题描述】:

我已经在几个地方阅读过它,并且在我的前辈的指导下在 java 中使用字符串常量。所以我通常将所有日志消息和其他必需的字符串内容保存在我的 StringConstants 类中,看起来像这样:

public class StringConstants {

    // Logger Messages
    // Debug
    public static final String DEBUG_ENTERING_METHOD = "Entering Method";
    public static final String DEBUG_LEAVING_METHOD = "Leaving Method";
}

我是否还应该在此文件中保留特殊字符/符号/运算符(例如 ':'、'、' 或 '=' 作为最终字符串?

我问这个是因为我知道如果 Strings 对象在内存中,它们不会一次又一次地创建。所以如果我必须做类似的事情

logger.error(StringConstants.ERROR_MSG+":"+some_string);

冒号应该在字符串常量中吗?对我有什么好处吗?

如果我的疑问或疑问不清楚,请在评论中提及,我会编辑问题。

【问题讨论】:

  • 对于记录器示例,我会像 logger.error(some_string) 一样使用 error 方法,其中 some_string 是错误消息。然后,该方法会以您喜欢的方式格式化此消息(例如,在字符串前面加上 "Error:")。
  • 这是一种观点,但对我来说,StringConstants 类的目的是将所有应用程序消息放在一个位置。这使得国际化更容易一些,以及更正任何拼写或语法错误。目的不是对 Java 进行微优化。
  • 为什么不将您的 StringConstants 扩展一个字符并在 StringConstants.ERROR_MSG 中包含 :?
  • 据我了解 logger.error("a"+"b"+"c") 会创建三个字符串对象吗?所以它不是内存有效的!最终的 String 对象将不会被再次创建..
  • @SambhavSharma 创建字符串只会在非常大的规模和短时间内成为内存问题。您可以对其进行测试,但可能在几秒钟内成千上万的字符串将开始显示效率变化。不用担心 O(10) 字符串。

标签: java string memory-management


【解决方案1】:

最好使用属性文件而不是类或接口来保存用于消息的字符串。您甚至可以将属性文件保存在包含您的 java 代码的 jar 之外。有几个优点。

如果您想更改消息的文本,或者为不同的语言设置不同的版本,您只需放置一个新的属性文件即可,无需重新构建 jar 文件。

如果您正确使用 PropertyResourceBundle 类,国际化会自动发生 - 您可以同时存在不同的属性集,系统的语言环境将用于选择正确的属性。

Logger 类与ResourceBundle 无缝集成,因此您无需编写任何代码来查找消息密钥。

Logger 类允许您使用包含消息参数(如 {0}, {1})并使用您提供的参数扩展它们。甚至还有一些格式化选项。因此,在您的问题示例中,您可能有一个值为Entering method {0} of class {1} 的属性,只需编写logger.log(Level.FINE, "entering", "methodname", "classname");,其中“进入”是属性文件中的键。这样就没有必要搞乱StringBuilder 对象、String.format 或任何其他消息连接机制。

有一些日志框架可以为您提供比这更多的好处,但是这个话题太大了,无法在这里讨论。我的观点是,使用一个属性文件和一个资源包会给你很多东西,而且毫无用处。因此,甚至没有必要考虑为您的常量创建一个类或接口。

【讨论】:

    【解决方案2】:

    IMO,应该在使用常量的地方定义常量。如果它们在一个类中使用,请在该类中定义它们。如果它们在一个包中使用,请在该包中的类中定义它们。在最合乎逻辑的地方定义它们,而不是在一个地方随意定义。

    如果您使用冒号作为分隔符,也许您需要一个常量,因为当您引用它时,它可能会更清楚地说明它的目的。但是仅仅为打印日志消息定义常量是相当愚蠢的,因为它们的确切格式无关紧要。并且所有具有相同值的字符串字面量都指向同一个对象,所以这个

    final String STRING = "string";
    System.out.println(STRING);
    System.out.println(STRING);
    

    ...本质上与

    相同
    System.out.println("string");
    System.out.println("string");
    

    两者都只创建一个字符串。

    顺便说一下,这个

    logger.error("a" + "b" + "c");
    

    ...可以创建 五个 字符串(“a”、“b”、“c”、“ab”和“abc”),尽管我认为编译器可能会识别出你是什么做并优化它。也许对编译器有更多了解的人可以对此有所了解。无论如何,除非您能证明性能是一个问题,否则不要担心微优化。你会付出很多努力,而用户永远不会注意到你减少了几毫秒。

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多