静态日历变量上的sonarqube错误
sonarqube error on static Calendar variable
我声明了以下变量:
private static Calendar calendar = Calendar.getInstance();
我在静态方法中使用该变量 'calendar',如下所示:
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
}
那么我该如何修复错误...在这种情况下我可以使用本地 Calendar
变量而不是 class 变量还是有任何其他聪明的方法来解决这个问题。
声纳警告是因为 calendar
对象可以从多个线程更新。
或者,正如您所说,您可以将 calendar
声明为方法的本地。
或 1) 在您的代码中创建一个同步块。 (使用本地 calendar
更好)
Date effValueDate ;
synchronized(calendar) {
calendar.setTime(some_date);
calendar.add(Calendar.DATE, value);
effValueDate = calendar.getTime();
}
- 推荐: 使用新的 java API 类 作为日期和时间 (
java.time
)。
// 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();
Read more关于新API
java.time
由于您似乎已经接受了 Gautham 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);
}
}
对我来说,与使用 Calendar
和 Java 1.0 和 1.1 中其他设计不佳的 类 的原始代码相比,它看起来不仅更简单,而且更易于阅读。
我正在利用这样一个事实,即您的字符串格式是日期的 ISO 8601 格式,LocalDate
解析为默认格式,即没有任何显式格式化程序。
我在我的时区 (Europe/Copenhagen) 试过这个电话:
myStaticMethod("2021-06-28");
输出为:
587995
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
我声明了以下变量:
private static Calendar calendar = Calendar.getInstance();
我在静态方法中使用该变量 'calendar',如下所示:
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
}
那么我该如何修复错误...在这种情况下我可以使用本地 Calendar
变量而不是 class 变量还是有任何其他聪明的方法来解决这个问题。
声纳警告是因为 calendar
对象可以从多个线程更新。
或者,正如您所说,您可以将 calendar
声明为方法的本地。
或 1) 在您的代码中创建一个同步块。 (使用本地 calendar
更好)
Date effValueDate ;
synchronized(calendar) {
calendar.setTime(some_date);
calendar.add(Calendar.DATE, value);
effValueDate = calendar.getTime();
}
- 推荐: 使用新的 java API 类 作为日期和时间 (
java.time
)。
// 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();
Read more关于新API
java.time
由于您似乎已经接受了 Gautham 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);
}
}
对我来说,与使用 Calendar
和 Java 1.0 和 1.1 中其他设计不佳的 类 的原始代码相比,它看起来不仅更简单,而且更易于阅读。
我正在利用这样一个事实,即您的字符串格式是日期的 ISO 8601 格式,LocalDate
解析为默认格式,即没有任何显式格式化程序。
我在我的时区 (Europe/Copenhagen) 试过这个电话:
myStaticMethod("2021-06-28");
输出为:
587995
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601