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

“检测”;超级";使用字节码的java代码中的word,java,bytecode,super,Java,Bytecode,Super,我目前正在尝试计算java程序中超级调用的数量。换句话说,我想计算给定代码中“super”的数量。我曾尝试使用操作码中的invokespecial方法,但问题是它会计算“super”一词出现的其他情况 他不在场 我将非常感谢任何帮助,这个问题一直是一个巨大的痛苦 //编辑 我想数一数“超级”这个词;callssuper是一个关键字,表示任何父类 您不需要super()调用计数,因为每个构造函数将有一个调用计数(除了java.lang.Object) 为了确保使用了super,您必须查看使用thi

我目前正在尝试计算java程序中超级调用的数量。换句话说,我想计算给定代码中“super”的数量。我曾尝试使用操作码中的invokespecial方法,但问题是它会计算“super”一词出现的其他情况
他不在场

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

//编辑
我想数一数“超级”这个词;calls

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

您不需要
super()
调用计数,因为每个构造函数将有一个调用计数(除了
java.lang.Object

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


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

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

要查找调用站点,如
super.method()
,可以查找满足以下条件的
invokespecial
指令:

  • 目标方法不是构造函数(即,未命名为
  • 目标方法的声明类型不是当前类型(用于筛选出私有方法)
  • 调用站点不是静态方法(见下文)
  • 第3项应处理误报,就像原始代码的表达式形式为
    OuterClass.this.privateMethod()
    时出现的误报一样。在这种情况下,编译器将发出一个静态访问器方法,该方法使用
    invokespecial
    OuterClass
    实例上调用
    privateMethod()

    如果要包含
    super()
    构造函数调用,则需要在调用另一个构造函数的构造函数中查找
    invokespecial
    指令;通过比较被调用构造函数的声明类型与当前类型,可以筛选出
    this()
    调用

    您无法可靠地确定原始源中何时显式使用了
    super.field
    ,因为在许多情况下(甚至是非限定访问),它在语义上等同于
    this.field
    。如果要包括任何超类字段访问,只需将字段的声明类型与任何
    getfield
    putfield
    指令的当前类型进行比较即可。否则,您所能做的就是确定必须使用
    super.field
    的位置,即目标字段被当前类中同名字段隐藏的任何字段访问


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

    不能只解析
    .java
    文件吗?的确,这是一个选项,但我更喜欢字节码解决方案。如果我使用解析器,我还必须计算我想要避免的构造函数!尤克萨里斯托·潘托斯:-)谢谢彼得,我更新了问题。我想数一数所有的超级。有些东西不仅仅是超级呼叫。有什么区别?正如我所说,您不需要构造函数调用。invokespecial还用于调用私有方法。哦,您说得对!这会使事情变得棘手。将更新。更新以解决
    invokespecial
    以及
    OuterClass.super
    引用的其他边缘情况。另外,考虑到后者,我发现我的反编译器中有一个bug\o/