Finding out if a class has a class initializer without reading the class file
I wonder if there is a known way to find out if a loaded Class
class initializer has, i.e. compiled with the method <clinit>
. I know this method is invisible or invokable through reflection, but I want to copy the loaded class when applying some transformations.
I would like to avoid parsing the class file because I am overriding all the methods of that class, which effectively means that I do not need any information from the file, since all the information that matters to me is available from the loaded one Class
.
So my question is, is it possible to check a loaded Class
class initializer exists for existence?
source to share
After spending quite a bit of effort to figure it out and read it online: the subsystem ClassLoader
does not provide this information to the view Class
. Any information about the method is fetched from a native call that already filters out the method <clinit>
. On the JVM runtime side, there is only internal exposure, which can be used as a non-canonical way to figure out. For this, puprpse ObjectStreamClass
defines a static private method hasStaticInitializer(Class)
that is used to compute the implicit UID serialization, which is re-denoted with a UTF value <clinit>()V
and Modifier.STATIC
only if the class has a class initializer.
However, this match can be used to create a canonical way that does not use internal methods: by calculating the implicit sequential identifier manually, you can narrow this value down to two values, one value for the version Class
with a class initializer and one value for the same Class
without such an initializer. You can then further serialize the class literal and see what value the serialization engine returns. If this value represents a value that has been overwritten <clinit>()V
, the class is known to define such a method. Otherwise, it doesn't matter so much.
source to share