简体   繁体   English

无法更改静态最终变量

[英]Cannot change static final variable

public class TestData {
   public static final String DATA = "A"; // I change this to read DATA = "B"
}

public class MyTest extends UnitTest {
   private MyClass myClass;

   public void setUp() {
      myClass = new MyClass(TestData.DATA); // After change, DATA has value "B"
   }
}

public class MyClass {
   private String myVar;

   public MyClass(String myVar) { // After change, myVar still has value "A"
      this.myVar = myVar;   
   }
}
  1. Change TestData.DATA to B by editing the source code in Eclipse 通过在Eclipse中编辑源代码,将TestData.DATA更改为B
  2. Restart server 重新启动服务器
  3. Run MyTest 运行MyTest
  4. MyClass still receives A when referencing TestData.DATA 当引用TestData.DATA时, MyClass仍然收到A
  5. ??? ???

Things I tried: restart server, eclipsify project, clean project, restart eclipse, restart computer, refresh every file manually. 我尝试过的事情:重新启动服务器,eclipsify项目,清理项目,重新启动eclipse,重新启动计算机,手动刷新每个文件。 I found this to work: 我发现这可行:

String data = TestData.DATA;
myClass = new MyClass(data);

Why can't I pass DATA directly to MyClass constructor? 为什么不能将DATA直接传递给MyClass构造函数?

I've got no error messages, when I break at setUp , DATA has the value "B" since I've changed it, but when I step into MyClass myVar has the value "A" 我没有错误消息,当我在setUp中断时,由于更改了DATA它的值为“ B”,但是当我进入MyClass时, myVar的值为“ A”

You can't change a final variable. 您不能更改final变量。 That's what makes it final . 这就是final But there is nothing wrong with passing the final variable to a function. 但是将final变量传递给函数并没有错。 In fact, the sample code that you posted runs just fine. 实际上,您发布的示例代码运行良好。

In your list of steps, you said 'change DATA to "B"' though your code doesn't show this step. 在步骤列表中,您说了“将DATA更改为“ B””,尽管您的代码未显示此步骤。 But that's fine, since that step wouldn't compile. 但这很好,因为该步骤无法编译。

If you need to alter a final variable before passing it to a function, you need to make a local copy and change that copy instead. 如果需要在将final变量传递给函数之前更改final变量,则需要制作一个本地副本并改为更改该副本。

Update: Now that the question has been clarified, here are some more thoughts: 更新:现在已经澄清了问题,这里有一些更多的想法:

It sounds like something isn't being recompiled properly. 听起来有些东西没有正确地重新编译。 Perhaps you are running from an old version of the classes (ie you need to copy it somewhere)? 也许您是从旧版本的类运行的(即,您需要将其复制到某个地方)?

Also, you should know that although you may change the TestData class, because DATA is declared static final , Java may have inlined that constant into the MyTest class (since it is guaranteed to never change) so you need to make sure that MyTest is also recompiled. 另外,您应该知道尽管可以更改TestData类,但由于DATA被声明为static final ,因此Java可能已将该常量内联到MyTest类中(因为保证永远不会更改),因此您需要确保MyTest也是重新编译。

If you want to verify that you are using the latest version of a class, put some very "loud" code in a place where you know it should execute. 如果要验证您使用的是最新版本的类,请将一些非常“响亮的”代码放在您应该执行的地方。 For example, a System.out.println or even throw a RuntimeException (sure, your program will fail, but if it doesn't fail then you know that something isn't being recompiled properly which will help you diagnose what is wrong). 例如,一个System.out.println甚至抛出RuntimeException (当然,你的程序将失败,但是如果它不那么失败,你知道自己是不是被重新编译正确,这将帮助你诊断什么是错的)。

You need to make sure that all the .java files are being compiled between runs, Eclipse has a cache that gets out of sync some times. 您需要确保在运行之间编译所有.java文件,Eclipse的缓存有时会不同步。 Doing a clean on the project should clear up your problems 对项目进行清理应该可以解决您的问题

After changing the TestData class, you have to recompile the other classes. 更改TestData类后,您必须重新编译其他类。 The reason is that constant expressions are resolved at compile time, not at run time. 原因是常量表达式是在编译时而不是在运行时解析的。

Try manually cleaning, does that work? 尝试手动清洁,行得通吗? Chances are its caching things on compilation and then not refreshing the contents when it should. 可能是它在编译时缓存内容,然后在需要时不刷新内容。 I've seen similar behaviour with Netbeans over static final fields, and cleaning has generally solved it. 我已经在静态的final字段上看到了与Netbeans类似的行为,清理通常可以解决它。

If this does prove the case, and a full build doesn't take too long, the easiest thing to do is probably modify the ant task so before every run it does a clean (and so is forced to recompile the classes it needs from scratch.) 如果确实可以证明这种情况,并且完整构建不会花费太长时间,那么最简单的操作可能就是修改ant任务,以便在每次运行之前进行一次清理(因此被迫从头开始重新编译所需的类) )

You need to make sure that your class gets recompiled to wherever your server is reading the class files from. 您需要确保将类重新编译到服务器从中读取类文件的任何位置。 It's cached somewhere, hence the old value of DATA . 它缓存在某个地方,因此是DATA的旧值。

Why do you say that you can't pass DATA to the MyClass constructor? 为什么说不能将DATA传递给MyClass构造函数?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM