Reputation: 635
I'm seeing some very strange behavior in a java program. The failure is not reproducible, so all I have to go on is the original logs.
The class looks something like this:
public class MyClass {
public static final String MY_CONSTANT_STRING = "This should never change";
public boolean checkEndsWithCS(String inString) {
return inString.endsWith(MY_CONSTANT_STRING);
}
public String getString() {
return "Some text '" + MY_CONSTANT_STRING + "' some more text";
}
}
In the logs, I see a case where getString returns "Some text '' some more text" and checkEndsWithCS("These are not the chars you're looking for.") returns true.
I can only conclude that MY_CONSTANT_STRING is "" in this case.
No other class extends MyClass, so it's not getting overridden in a higher level class.
I don't see any sign of an out of memory condition in the log, which would seem like the most likely cause.
It's static final, so the reference shouldn't change. Strings are immutable, so the string shouldn't change.
Questions:
If the collective experience here can't break this loose, then I'll just take it as a sign that my data are faulty and examine it from that angle.
Upvotes: 1
Views: 270
Reputation: 718866
It is possible to use Java reflection to change the values of final
fields, or mess around with the private fields of a String
object.
It is also possible for native code (e.g. native
methods) to overwrite memory, and that could potentially lead to some String object's length changing to zero.
If something in your code-base is doing this kind of stuff, it is going to be difficult to identify the culprit. And you shouldn't entirely overlook possibilities like:
Or you might not be running code that matches the source code that you are looking at.
1) When do these execute? I set a breakpoint in eclipse, and it never gets hit. I put a breakpoint on the assignment of MY_CONSTANT_STRING ...
That code gets executed as part of the static initialization of the class. Maybe it was executed before you set the breakpoint. Or maybe there is a bug in the debugger.
2) Is there any possible way for an immutable string in a static final reference to change?
Yes. See above.
3) Is there any possible way for the string not to get assigned in the first place?
Given just your code as written here, No. However, if you have a cycle in the static initialization graph, it is possible to see the value of MY_CONSTANT_STRING
before it has been assigned. However, that value will be null
... not an empty string.
4) Is there any way the memory containing the string or reference could be getting "clobbered" by some other object or process?
Yes. See above.
5) Any other subtle gotchas where I'm just not thinking about this the right way?
Possibly. I can't read your mind from this distance :-)
Upvotes: 3
Reputation: 66886
Almost surely, either:
static
assignments and initializers happen when the class is initialized, before any methods of the class are called or instances created. This is guaranteed. String
is immutable, and final
references do not change after assignment. You can't override fields, ever, and can't override anything static, ever. (Though you can hide them for sure.)
The only other value you could possibly observe for this field is null
, which would happen if it is final
but you reference it in a static
block before it is assigned -- which is hard to do, can only happen in a sort of circular initialization scenario.
Barring a JVM bug -- and, this is not utterly impossible -- no a reference can't be corrupted by any action of Java code.
Upvotes: 2