我现在专注于需要洞察Java字节码的项目。如何识别Java字节码中的覆盖方法?
在bcel的帮助下,我现在可以完成大部分工作。有一点,我现在不清楚如何识别子类方法覆盖其基本代码?在指示此重写关系的方法中是否存在与.class
文件关联的任何属性,还是应该向后返回其基类可以比较方法签名?
任何提示将不胜感激。
我现在专注于需要洞察Java字节码的项目。如何识别Java字节码中的覆盖方法?
在bcel的帮助下,我现在可以完成大部分工作。有一点,我现在不清楚如何识别子类方法覆盖其基本代码?在指示此重写关系的方法中是否存在与.class
文件关联的任何属性,还是应该向后返回其基类可以比较方法签名?
任何提示将不胜感激。
您需要查看层次结构链 - 字节码中没有任何内容表明它是重写的方法,因为不需要。
您可以对其进行反编译并将代码作为您选择的IDE中的项目加载。通常,您可以轻松地跳转到继承类的重写方法。
感谢您的快速响应。但是如何用Java代码实现这一点? :) –
不幸的是,你不能从字节码中知道。注释@Override只是一个建议性的 - 它不是强制性的。
JVM定义了5种调用方法的方法。它们是invokevirtual,invokeinterface,invokespecial,invokestatic和新的invokedynamic。
关注invokevirtual - 这是最常见的调度形式,并且是您在此处讨论的情况下使用的一种。
invokevirtual的工作方式是在运行时查看要分派的对象的类。如果它找到了我们之后的方法的实现,那么它会调用它。如果不是,那么它会查看对象类的超类并再次尝试,等等。
因此,没有办法从字节码中可靠地判断给定的方法是否被覆盖,而无需查看父类的字节码。
编译后生成字节码。因此,它只假定基于引用变量调用的方法,因为该对象尚未创建。
为什么没有必要?那么JVM如何动态链接不同的'.class'文件呢?它是否自下而上搜索固有的层次结构,直到找到匹配的方法为止?谢谢。 –
@Summer_More_More_Tea翻转问题 - 为什么*有必要?如果它是您正在查看的课程的一种方法,为什么虚拟机需要知道它被覆盖? –
@ DAVE听起来很赞。:)谢谢。 –