使用字节码检测java代码中的“超级”字

时间:2013-12-04 18:06:21

标签: java bytecode super

我目前正在尝试计算java程序中超级调用的数量。换句话说,我想计算给定代码中“超级”的数量。我试图使用opcode中的invokespecial方法,但问题是它计算了“super”这个词的其他情况 不存在。

我会非常感谢任何帮助,这个问题一直是一个巨大的痛苦!

//编辑 我想计算super.something案例而不仅仅是super();呼叫

2 个答案:

答案 0 :(得分:2)

super严格来说是Java语言级标识符;字节码中没有直接的等价物。

要查找super.method()等通话网站,您可以查找符合以下条件的invokespecial条款说明:

  1. 目标方法不是构造函数(即,未命名为<init>)。
  2. 目标方法的声明类型不是当前类型(过滤掉私有方法)。
  3. 呼叫站点不是静态方法(见下文)。
  4. 项目#3应该处理误报,就像原始代码具有OuterClass.this.privateMethod()形式的表达时那样。在这种情况下,编译器会发出一个静态访问器方法,该方法使用invokespecialprivateMethod()实例上调用OuterClass,并且您不希望包含这些。

    如果要包含super()构造函数调用,则需要在构造函数中查找调用另一个构造函数的invokespecial指令;您可以通过将调用的构造函数的声明类型与当前类型进行比较来过滤掉this()调用。

    您无法可靠地确定原始来源中super.field 显式的使用时间,因为在许多情况下(甚至是不合格的访问权限),它在语义上等同于this.field。如果要包含任何超类字段访问权限,只需将字段的声明类型与任何getfieldputfield指令的当前类型进行比较即可。否则,您可以做的最好的事情是确定已使用super.field 必须的地方,即目标字段被当前类中具有相同名称的字段隐藏的任何字段访问。 / p>

    如果您想检测OuterClass.super.privateMethod()形式的访问,那么您会遇到一些痛苦。编译器为这些方法生成静态访问器方法,并且约定是编译器的实现细节,因此可靠地识别它们并非易事。您还必须分析生成的方法以验证调用的方法的声明类型与实例参数类型不匹配(假设编译器实际将参数键入为OuterClass并且不直接替换其超类)。如果代码被混淆了,请忘掉它。

答案 1 :(得分:0)

super是一个关键字,表示任何父类。

您不需要super()次呼叫计数,因为这些将是每个构造函数一个(java.lang.Object除外)

为了确保使用super,您必须查看使用this作为父类的非静态方法的第一个参数的方法。

您可以执行类似于对父类字段的计数访问。