简体   繁体   中英

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
  2. Restart server
  3. Run MyTest
  4. MyClass still receives A when referencing TestData.DATA
  5. ???

Things I tried: restart server, eclipsify project, clean project, restart eclipse, restart computer, refresh every file manually. I found this to work:

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

Why can't I pass DATA directly to MyClass constructor?

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"

You can't change a final variable. That's what makes it final . But there is nothing wrong with passing the final variable to a function. 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. 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.

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.

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).

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. Doing a clean on the project should clear up your problems

After changing the TestData class, you have to recompile the other classes. 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.

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.)

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 .

Why do you say that you can't pass DATA to the MyClass constructor?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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