当前位置: 首页 > 面试题库 >

调用静态java.text.DateFormat的方法不建议吗?

滑畅
2023-03-14
问题内容

我收到“ 查找错误” 错误- 调用静态java.text.DateFormat方法,
并且我不知道为什么在下面做这些事情不好/不建议这样做的原因。

private static final Date TODAY = Calendar.getInstance().getTime();
private static final DateFormat yymmdd = new SimpleDateFormat("yyMMdd");

private String fileName = "file_" + yymmdd.format(TODAY);

问题答案:

DateFormat不是线程安全的,这意味着它们维护状态的内部表示。如果多个线程同时访问同一实例,则在静态上下文中使用它们会产生一些非常奇怪的错误。

我的建议是使变量在使用变量的位置本地化,而不是使它们成为类的静态属性。初始化类时似乎正在执行此操作,因此可以在构造函数中执行此操作:

public class MyClass {
    private String fileName;

    public MyClass() {
        final Date today = Calendar.getInstance().getTime();
        final DateFormat yymmdd = new SimpleDateFormat("yyMMdd");

        this.fileName = "file_" + yymmdd.format(TODAY);
    }
    ...
}

如果需要在多个地方使用格式化程序,则可以制作模式static finalDateFormat在需要时创建新的本地:

public class MyClass {
    private static final String FILENAME_DATE_PATTERN = "yyMMdd";

    public void myMethod() {
        final DateFormat format = new SimpleDateFormat(FILENAME_DATE_PATTERN);
        // do some formatting
    }
}

该问题的FindBugs文档说:

如JavaDoc所述,DateFormats本质上对于多线程使用是不安全的。检测器已找到对通过静态字段获得的DateFormat实例的调用。这看起来很可疑。

有关更多信息,请参见Sun Bug#6231579和Sun Bug#6178997。

而且DateFormat的javadoc建议:

日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部进行同步

Jack Leow的答案也很好地说明了您静态使用“TODAY”的语义。
我不确定FindBugs是否对此抱怨,但是我在您的代码中看到的一个问题是您将其定义TODAY为类级别(静态),常量(最终)变量。这传达了您TODAY永远都不要改变的意图(我不相信这种情况,因为java.util.Dates是可变的,但这是另一回事了)。

考虑一下如果您的应用程序运行多天会发生什么?TODAY(除非您对其进行更新)将引用应用程序启动的日期,而不是当前日期。您确定这是您的意思吗?

这可能根本不是代码中的错误,但目的尚不清楚,我相信这可能是FindBugs抱怨的地方。

顺便说一句,我实际上已经在高流量的生产环境中看到了这种情况,一开始调试起来是一件非常令人困惑的事情。因此,以我的经验,FindBugs警告实际上是一个有用的建议(与其他一些静态分析规则不同,有时看起来有些挑剔)。



 类似资料:
  • 我最近对 PHP 5.4 进行了更新,但收到有关静态和非静态代码的错误。 这是错误: 这是第371行: 我希望有人能帮忙。

  • 一些日志记录需要在类的静态方法执行前后完成。我试图使用Spring AOP实现这一点,但它不起作用,对于普通方法来说,它是起作用的。请帮助我理解如何实现这一点,如果可以使用注释来完成,那就太好了。

  • 我正在使用存储库模式并尝试建立模型之间的关系。当我尝试运行存储()方法(在控制器中),该方法试图使用用户()方法(与方模型建立关系)时,我收到以下错误消息: 非静态方法不应该静态调用::user(),假设$this来自不兼容的上下文 我不明白为什么在尝试运行user()relationship方法时会出现此错误,但所有其他方法(包括$this- 以下是相关代码:

  • 我已经用原始切入点和建议方法编写了简单方面: 我有以下基于Spring注释的应用程序配置: 和com中的实用程序类。mtag。util包: 但是当我打电话的时候 在单元测试中,我可以看到方法调用没有被拦截,我的@AfterResning建议不起作用。 但如果我将someMethod()类型更改为实例(非静态)方法,则切入点为 通过添加@Component注释和调用目标metod来管理Spring的

  • 我一直试图用我的验证代码进行php pear验证,但我收到的都是严格标准错误--问题是什么?我如何修复它? 电子邮件验证.php

  • PHP严格标准:不应在第33行的/web/sites/blah/somescript.PHP中静态调用非静态方法pear::iserror() 我在MDB2上看到了类似的错误。稍后再详细介绍。 somescript.php: 问题 是否有不同的方法来调用而不会产生错误?