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