【问题标题】:Sonar - Make DATE_FORMAT as instance variable声纳 - 将 DATE_FORMAT 作为实例变量
【发布时间】:2019-07-25 11:44:44
【问题描述】:

我有一个休息网络服务,下面是我声明 DateFormat 的方式,因为这是我将在应用程序范围内使用的日期格式。

当我使用 SonarLint eclipse 插件进行代码分析时,我收到了主要警告“将 DATE_FORMAT 设为实例变量。”

public class Constants {

    private Constants() {

    }

    public static final DateFormat DATE_TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSS");

}

谁能告诉我如果我在我的 REST API 中以这种方式使用它可能会遇到什么问题?
如果我将它用作实例变量,我最终会在多个类中声明它吗?

【问题讨论】:

  • 拥有一个类来保存常量是反模式。你最终会在你的类中拥有这些彼此不相关的常量。
  • 另外,DateFormat 是可变的,所以如果以多线程方式使用,可能会得到错误的结果。

标签: java sonarqube sonarlint


【解决方案1】:

触发的规则是S2885:

非线程安全字段不应是静态的

鱿鱼:S2885

并非标准 Java 库中的所有类都被编写为线程安全的。以多线程方式使用它们极有可能在运行时导致数据问题或异常。 当 Calendar、DateFormat、javax.xml.xpath.XPath 或 javax.xml.validation.SchemaFactory 的实例标记为静态时,此规则会引发问题。

由于SimpleDateFormat 不是线程安全的,它不能很好地在线程之间共享。您很可能会以错误的日期格式结束。

如果您使用的是 Java 8 或更高版本,则应使用DateTimeFormatter,如this answer。否则,根据this answer,使用 Joda Time 是有意义的。


作为旁注,拥有一个名为Constants end 的类让它包含各种静态最终变量很少有意义。通常你应该把每个常量放在它所属的地方。

【讨论】:

    【解决方案2】:

    静态变量主要用于常量。
    在这里,您已声明静态并为其分配 SimpleDateFormat 的实例。
    要么将DATE_TIME_FORMAT 设为非静态,要么为该变量分配一个常量。

    最好将其更改为实例变量并使用 Sting 来执行此操作。
    例如 public final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss:SSS";

    【讨论】:

      【解决方案3】:

      使用 joda-time 或简单地用方法替换变量:

      public static final DateFormat getDateTimeFormat() {
          return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss:SSS");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-08-04
        • 1970-01-01
        • 2012-11-28
        • 1970-01-01
        • 1970-01-01
        • 2020-03-22
        • 2015-04-26
        • 1970-01-01
        相关资源
        最近更新 更多