我想知道是否有一种已知的方法可以找出加载Class
的是否具有类初始化程序,即使用<clinit>
方法编译。我知道此方法不可见或无法通过反射调用,但我想在应用一些转换时复制加载的类。
我想避免解析类文件,因为我重新定义了这个类的所有方法,这实际上意味着我不需要文件中的任何信息,因为与我相关的所有信息都可以从加载的Class
.
因此我的问题是:是否可以检查已加载Class
的类初始化程序是否存在?
我想知道是否有一种已知的方法可以找出加载Class
的是否具有类初始化程序,即使用<clinit>
方法编译。我知道此方法不可见或无法通过反射调用,但我想在应用一些转换时复制加载的类。
我想避免解析类文件,因为我重新定义了这个类的所有方法,这实际上意味着我不需要文件中的任何信息,因为与我相关的所有信息都可以从加载的Class
.
因此我的问题是:是否可以检查已加载Class
的类初始化程序是否存在?
在花费了相当多的精力来挖掘并在网上阅读之后:ClassLoader
子系统不会将此信息暴露给Class
表示。任何方法信息都是从已经过滤掉<clinit>
方法的本机调用中检索的。在 JVM 运行时方面,只有内部暴露,可以用作一种非规范的查找方式。对于这个 puprpse,ObjectStreamClass
定义了一个静态的私有方法hasStaticInitializer(Class)
,用于计算隐式序列化 UID,该 UID 由 UTF 值重新散列,<clinit>()V
并且Modifier.STATIC
仅当类具有类初始化器时。
然而,这种巧合可用于创建一种不使用内部方法的规范方式:通过手动计算隐式序列 ID,可以将此值缩小为两个值,一个值用于Class
具有类初始值设定项的 a 版本,一个值用于Class
没有这样的初始化程序也是如此。然后可以另外序列化类文字并查看序列化引擎返回的值。如果此值表示由 重新散列的值,则<clinit>()V
知道该类定义了这样的方法。否则,它没有这样的值。