javaclasstypeinitializer

Finding out if a class has a class initializer without reading the class file


I wonder if there is a known way of finding out if a loaded Class has a class initializer, i.e. is compiled with a <clinit> method. I know that this method is not visible or invokable via reflection but I want to copy a loaded class while applying some transformations.

I would like to avoid the parsing of the class file because I redefine all methods of this class, which effectively means that I do not need any information from the file as all information that is relevant to me is available from the loaded Class.

Thus my question: Is it possible to check a loaded Class for the existence of a class initializer?


Solution

  • After spending quite some efforts on digging through this and reading up on the web: The ClassLoader subsystem does not expose this information to the Class representation. Any method information is retrieved from a native call which is already filtering away the <clinit> method. On the JVM runtime side of things, there is only internal exposure, which can be used as a non-canonical way of finding out. For this puprpse, the ObjectStreamClass defines a static, private method hasStaticInitializer(Class) which is used to compute an implicit serialization UID which is rehashed by the UTF value of <clinit>()V and Modifier.STATIC only if a class has a class initializer.

    This coincidence can however be used to create a canonical way which does not use internal methods: By computing the implicit serial ID manually one can narrow this value down to two values, one value for a version of a Class with a class initializer and one value for the same Class without such an initializer. One can then additionally serialize the class literal and see what value the serialization engine returns. If this value represents the value that was rehashed by <clinit>()V, one knows that the class defines such a method. Otherwise, it does not have such a value.