gpt4 book ai didi

Java常量在不同的地方是不同的

转载 作者:行者123 更新时间:2023-11-30 08:09:40 24 4
gpt4 key购买 nike

因此,我们已经将一些东西投入生产,并且运行良好。但是,我在日志中看到一些非常令人不安的东西。即:

pr 0.1 -  wait time for fetchAndRemoveEntries: 0
pr 1.0 - f'n'r entries: uid: hbyk68jfhbf5th

请注意,pr 对于这两行是不同的。运行代码搜索 wait time for fetchAndRemoveEntries 仅返回一个结果,f'n'r entries 也是如此。两者都是 println。第一个是在我们的一个 API 类中找到的:

System.out.println("pr " + NotificationDataStorage.printReduction + " -  wait time for fetchAndRemoveEntries: " + (System.currentTimeMillis() - startTime));

第二个位于我们的类 NotificationDataStorage 中,其中定义了 printReduction。该类的缩写版本:

public class NotificationDataStorage {
public static final double printReduction = 1;
...
public static void addEntries(ArrayList<HashMap> data) {
... // No, I have did not declare 'printReduction' as a local variable.)
System.out.println("pr " + printReduction + " - adding " + data.size() + " entries");
...
}
...
}

即使忽略“addEntries”代码,NotificationDataStorage.printReduction 返回 0.1 而实际上它应该为 1 的事实也非常令人担忧。

实际上,我们整个星期都被这样的问题所困扰,尽管直到现在它们总是在我们推送到服务器时消失。我们假设它们是本地怪癖,也许是 NetBeans 的缺陷。我在调试器中单步调试代码,查看传递给方法 A 的常量,当我进入 A 的范围时,看到它更改为以前构建的值。旧值导致代码崩溃。我将它设置为记录一些事情,问题神秘地消失了。我们的代码莫名其妙地不起作用,但在 check out 不同的分支并返回到不起作用的分支后,它突然又开始工作了。清洁和 build 有时会修复它。有时不是。

部分奇怪的是,据我所知,这是我们遇到这些问题的第一周。就好像一周前我们写了一些代码,它的位现在召唤了一个恶魔来扰乱我们的常量。或者,更准确地说,就好像当我们更新常量时,更改仅反射(reflect)在使用它们的某些地方。

当前出现的特定问题没有问题,但非常担心其他常量可能会遇到类似问题。

有没有人对此有任何见解、经验或解释?

最佳答案

这几乎可以肯定是因为并非所有代码都被重新编译。

您的字段是 public static final double,它将在编译时获取内联值。如果值发生变化,这是一个巨大的问题,因为没有重新编译的旧类将不会更新它们的值!如果引用该字段的代码在不同的 jar 中,它可能也不会被重新编译。

The Java Security Coding Guidelines DCL59-J涵盖了这个问题

The final keyword can be used to specify constant values (that is, values that cannot change during program execution). However, constants that can change over the lifetime of a program should not be declared public final. The Java Language Specification (JLS) [JLS 2013] allows implementations to insert the value of any public final field inline in any compilation unit that reads the field. Consequently, if the declaring class is edited so that the new version gives a different value for the field, compilation units that read the public final field could still see the old value until they are recompiled. This problem may occur, for example, when a third-party library is updated to the latest version but the referencing code is not recompiled.

解决方案是将字段设为private 并改用公共(public)静态getter 方法。

 private static final double PRINT_REDUCTION = 1; //will change often

public static double getPrintReduction(){
return PRINT_REDUCTION;
}

请注意,我还大写了字段,这是常量的 Java 编码约定。

Java Coding Guidelines Recommendations Book 中涵盖了该主题和更多问题

关于Java常量在不同的地方是不同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32280675/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com