2011-12-01 85 views
6

我现在专注于需要洞察Java字节码的项目。如何识别Java字节码中的覆盖方法?

bcel的帮助下,我现在可以完成大部分工作。有一点,我现在不清楚如何识别子类方法覆盖其基本代码?在指示此重写关系的方法中是否存在与.class文件关联的任何属性,还是应该向后返回其基类可以比较方法签名?

任何提示将不胜感激。

回答

5

您需要查看层次结构链 - 字节码中没有任何内容表明它是重写的方法,因为不需要。

+0

为什么没有必要?那么JVM如何动态链接不同的'.class'文件呢?它是否自下而上搜索固有的层次结构,直到找到匹配的方法为止?谢谢。 –

+1

@Summer_More_More_Tea翻转问题 - 为什么*有必要?如果它是您正在查看的课程的一种方法,为什么虚拟机需要知道它被覆盖? –

+0

@ DAVE听起来很赞。:)谢谢。 –

-1

您可以对其进行反编译并将代码作为您选择的IDE中的项目加载。通常,您可以轻松地跳转到继承类的重写方法。

+0

感谢您的快速响应。但是如何用Java代码实现这一点? :) –

2

如果你不能依赖于@Override属性,那么看起来根据the spec,只需要看类就没有别的办法。我认为你需要看看超类。

+4

'@ Override'具有[SOURCE](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/annotation/RetentionPolicy.html#SOURCE)保留。 –

+0

@DᴀᴠᴇNᴇᴡᴛᴏɴ:谢谢。 – opqdonut

+0

@ DAVE +1。也感谢opqdonut的回复。 –

2

不幸的是,你不能从字节码中知道。注释@Override只是一个建议性的 - 它不是强制性的。

JVM定义了5种调用方法的方法。它们是invokevirtual,invokeinterface,invokespecial,invokestatic和新的invokedynamic。

关注invokevirtual - 这是最常见的调度形式,并且是您在此处讨论的情况下使用的一种。

invokevirtual的工作方式是在运行时查看要分派的对象的类。如果它找到了我们之后的方法的实现,那么它会调用它。如果不是,那么它会查看对象类的超类并再次尝试,等等。

因此,没有办法从字节码中可靠地判断给定的方法是否被覆盖,而无需查看父类的字节码。

0

编译后生成字节码。因此,它只假定基于引用变量调用的方法,因为该对象尚未创建。