How the hell did I miss that?

I’ve been doing Java since 1998, and yet I only just discovered this interesting fact. If you have a class called, say, DBAsset that has a bunch of static methods in it, and you have some static member variables, and you initialize the static member variables, like so:

class DBAsset
{
static PreparedStatement insertStmt = null;
static PreparedStatement deleteStmt = null;

Then calling multiple static methods from within DBAsset’s static main using just the unadorned method name doesn’t do anything to those variables, but each time you call one of those static methods from some other class using DBAsset.methodname, those static variables get reinitialized to null. Huh.

Update: Figured it out. The code that initialized the variables was getting called *before* the code that set it to null, because I had a static DBAsset theAsset = new DBAsset(); before the static initializers. I’m such a slaphead.

4 thoughts on “How the hell did I miss that?”

  1. It can’t be. Not only were the designers of Java not *quite* that insane, but a minimal test program fails to show this spurious reinitialization of static fields. There must be something else going on — if not the obvious, then maybe someone monkeying with class loading?

  2. (Um. I’m assuming this is part of a large and, uh, not-well-understood codebase; thus the slightly uncharitable “monkeying with” comment.)

  3. This is my code, very new and very small. Nobody else is using it or monkeying with it.

    I put a System.out.println in the code where insertStmt was initialized, and where it was used, and somewhere between being initialized (and it was printing out as non-null) and it being used, it just spontaneously changed to null. The only other culprit was the “private static PreparedStatement insertStmt = null;”. I took out the “= null”, and it worked perfectly.

  4. I apologize for the unintended insult, then.

    This has bothered me enough to go rummaging through the Java Language Spec (third edition) and find section 12.7, Unloading of Classes and Interfaces[*]. But I can’t tell if it’s attempting a “must not” or a “should not” or what.

    So, my best guess is that, assuming there are no actual instances of DBAsset floating around, the runtime thinks no-one cares about the class, unloads it, and then reloads it later when someone else refers to it — and the spec feels that this Really Shouldn’t Happen, but is unable to entirely forbid it, and why would a decent Java program have an uninstantiated class with actual state?

    (Which could explain why I can’t reproduce it: my little test program with an int counter isn’t generating any memory pressure, or my JRE is different, or both.)

    [*] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7 (and hopefully the URL won’t be a problem)

Comments are closed.