3

我想知道是否有一种已知的方法可以找出加载Class的是否具有类初始化程序,即使用<clinit>方法编译。我知道此方法不可见或无法通过反射调用,但我想在应用一些转换时复制加载的类。

我想避免解析类文件,因为我重新定义了这个类的所有方法,这实际上意味着我不需要文件中的任何信息,因为与我相关的所有信息都可以从加载的Class.

因此我的问题是:是否可以检查已加载Class的类初始化程序是否存在?

4

1 回答 1

3

在花费了相当多的精力来挖掘并在网上阅读之后:ClassLoader子系统不会将此信息暴露给Class表示。任何方法信息都是从已经过滤掉<clinit>方法的本机调用中检索的。在 JVM 运行时方面,只有内部暴露,可以用作一种非规范的查找方式。对于这个 puprpse,ObjectStreamClass定义了一个静态的私有方法hasStaticInitializer(Class),用于计算隐式序列化 UID,该 UID 由 UTF 值重新散列,<clinit>()V并且Modifier.STATIC仅当类具有类初始化器时。

然而,这种巧合可用于创建一种不使用内部方法的规范方式:通过手动计算隐式序列 ID,可以将此值缩小为两个值,一个值用于Class具有类初始值设定项的 a 版本,一个值用于Class没有这样的初始化程序也是如此。然后可以另外序列化类文字并查看序列化引擎返回的值。如果此值表示由 重新散列的值,则<clinit>()V知道该类定义了这样的方法。否则,它没有这样的值。

于 2014-08-20T14:17:33.107 回答