Question

as in a way to check appropriate use of a static registry:

class AClass {
     static final IDType = IDregistry.registerId(...);
}

class IDRegistry {
     public static registerId(...)
     {
          if(isCalledInStaticInitializer()) {
               return(new IDType(...));
          }
          assert false : "NO NO - can't do this !!!";
     }
}
Was it helpful?

Solution

I don't think you should do this. But if you insist, this would get you started:

public static boolean isCalledInStaticInitializer()
{
    for (StackTraceElement ste : Thread.currentThread().getStackTrace())
    {
        if("<clinit>".equals(ste.getMethodName()))
        {
            return true;
        }
    }
    return false;
}

Source: In section 2.9 of the JVM Specification ("Special Methods"):

"A class or interface has at most one class or interface initialization method and is initialized (§5.5) by invoking that method. The initialization method of a class or interface has the special name <clinit>"

OTHER TIPS

Your intention is unnecessary (no one ever does it - I've never seen it etc).

What you want is simply this:

static final IDType id = new IDType(...);

If you need to register the ID somewhere, put that code in the constructor of IDType if the IDType is immutable, or if it's mutable (unlikely) one option would be to use a factory method in IDType to create-and-register:

public class IDType() {
    ...
    public static IDType createAndRegister(...) {
        IDType idType = new IDType(...);
        SomeClass.register(idType);
        return idType;
    }
}

Static initialization is done on a per-class basis. So the question the question you might need to ask yourself is "which class's static initialization?". From your use case it looks like the IDRegistry's static initialization is run before any of the classes that register themselves. You might take a different approach and look at something else that you want to enforce about what can be added to the registry.

BTW you detect within a single class's initialization process, by using a final variable that you declare at the very beginning on the class, and then set in a static block at the very end of the class. Since static initialization is done in source order, any code executed as part of the classes static initialization, will see the java default value for the type (i.e. false, 0, null), and any code executed after static initialization will see the final set value.

class AClass {
    static final boolean staticInitDone;

    // Any static initialization done here will see
    // staticInitDone as false, e.g. the
    // Y constructor below would see false.
    static X = new Y();


    static {
        staticInitDone = true;
    }
}

But you'll note this doesn't adapt to the cross-class coordination that you want.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top