当前位置: 首页 > 知识库问答 >
问题:

静态日历变量上可能存在错误

缪兴腾
2023-03-14

我声明了以下变量:

private static Calendar calendar = Calendar.getInstance();

我在静态方法中使用变量'日历',如下所示:

myStaticMethod(String reqDate){
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
    Date some_date;
    long seconds = 0;
    int value = 10;
    try {
        some_date = df.parse(reqDate);
        calendar.setTime(some_date);
        calendar.add(Calendar.DATE, value);
        Date effValueDate = calendar.getTime();
        seconds = (effValueDate .getTime() - System.currentTimeMillis()) / 1000;
    } catch (ParseException e) {
        //---Do---something----
    }
}

我得到以下声纳错误:

Make "calendar" an instance variable.
Not all classes in the standard Java library were written to be thread-safe. 
Using them in a multi-threaded manner is highly likely to cause data problems or exceptions at runtime.    
This rule raises an issue when an instance of Calendar, DateFormat, 
javax.xml.xpath.XPath, or javax.xml.validation.SchemaFactory is marked static.

这是我的解决方案,但我不确定解决方案的质量是否足够好。

myStaticMethod(String reqDate) {
    Calendar calendar = Calendar.getInstance();
    // the do the next processing
}

在这种情况下,我可以使用本地日历变量来代替类变量吗?或者有其他聪明的方法来解决这个问题。

共有2个答案

柳英豪
2023-03-14

由于您似乎已经接受了Gautam M的建议,使用java.time,现代Java日期和时间API,我认为作为补充,我将使用java.time.重写您的方法,我可能不需要补充说,我完全同意这项建议。

public static void myStaticMethod(String reqDate) {
    int value = 10;
    try {
        LocalDate dateThen = LocalDate.parse(reqDate).plusDays(value);
        ZonedDateTime dateTimeThen = dateThen.atStartOfDay(ZoneId.systemDefault());
        long seconds = ChronoUnit.SECONDS.between(Instant.now(), dateTimeThen);
        System.out.println(seconds);
    } catch (DateTimeParseException dtpe) {
        //---Do---something----
        System.out.println(dtpe);
    }
}

对我来说,它看起来不仅更简单,而且比使用日历的原始代码和Java1.0和1.1中其他设计不佳的类更自然。

我正在利用这样一个事实,即您的字符串格式是日期的ISO 8601格式,LocalDate解析为默认格式,也就是说,没有任何显式格式化程序

我在我的时区(欧洲/哥本哈根)试过这个电话:

    myStaticMethod("2021-06-28");

产出为:

587995

  • Oracle教程:解释如何使用java的日期时间。时间
鞠自明
2023-03-14

sonar警告是由于可以从多个线程更新日历对象而引起的。或者,正如您所说,您可以将日历声明为该方法的本地。

或者1)在代码中创建一个同步块。(使用本地日历更好)

Date effValueDate ;
synchronized(calendar) {
    calendar.setTime(some_date);
    calendar.add(Calendar.DATE, value);
    effValueDate = calendar.getTime();
}
// or use DateTimeFormatter.ISO_LOCAL_DATE
DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd");

LocalDateTime date = LocalDate.parse(reqDate, pattern).plusDays(value).atStartOfDay();
Duration duration= Duration.between(date, LocalDateTime.now());
long seconds = duration.getSeconds();           

了解更多有关新API的信息

 类似资料:
  • 问题内容: 以下代码在变量上产生了错误,con2说 我用Google搜索解决方案,并且他们暗示尚未初始化该变量以使方法可用。我初始化不正确吗?我也尝试过将事情改为公开,但这也无济于事。 问题答案: 不,实际上,你必须声明con2字段为静态: 编辑:更正,实际上是远远不够的,你将遇到相同的问题,因为getConnection2Url方法也不是静态的。更好的解决方案可能是改为进行以下更改:

  • 我是Android编码的n00b,今天我想尝试使用定位服务。 我设置了一个简单的类和一个简单的main,只是为了得到经度和纬度。 但当我尝试调用retrive的构造时,long and latitude Android Studio弹出了一个错误: 错误:(33,16)错误:无法从静态上下文引用非静态变量纬度 这是我的位置班

  • 我编写了以下测试代码: 但会出现以下错误: 我如何让我的方法识别我的类变量?

  • 问题内容: 我已经定义了一个对象并声明了一个静态变量。在该方法中,当我尝试打印实例和类变量时,两者都打印相同的值。 不是实例变量吗?它应该打印0而不是50吗? 问题答案: 不,只有一个变量-您尚未声明任何实例变量。 不幸的是,Java允许您访问静态成员,就像通过相关类型的引用访问静态成员一样。这是IMO的设计缺陷,某些IDE(例如Eclipse)允许您将其标记为警告或错误- 但这是语言的一部分。您

  • 我现在正在编写这段代码,它总是在“教师x1=new Teacher();学生y1=new Student()”部分返回错误“非静态变量this cannot reference from a static context”。我不知道该怎么做才能让这个项目运转起来。谢谢你的帮助! 编辑:添加了其他类编辑2:此代码的目标是有一个类Person(带有姓名,年龄和性别),另一个类学生(带有等级)和教师(带

  • 我最近开始用Java编码,我有一个关于轮盘赌/挖掘游戏(终端)的问题。 每次尝试使用“bank.amount”购买特定商品时,都会出现以下错误: 这是我的shop.java文件 如果你需要更多的代码(例如,我的主类或银行类),请随时问我!