2011-12-01 7 views
6

私は現在、Javaバイトコードの洞察を必要とするプロジェクトに注力しています。Javaバイトコードでオーバーライドメソッドを識別する方法は?

bcelの助けを借りて、ほとんどの作業を完了できます。私が今はっきりしていない点の1つは、サブクラスメソッドを識別してベースコードをオーバーライドする方法です。 .classファイルには、このオーバーライド関係を示すメソッドに関連付けられた属性が記録されていますか?または、そのベースクラスに戻ってメソッドシグネチャを比較できますか?

ヒントは非常に高く評価されます。

答えて

5

階層チェーンをルックアップする必要があります。必要がないため、オーバーライドされたメソッドであることを示すバイトコードには何もありません。

+0

なぜそれは必要ないのですか?次に、JVMが '.class'ファイルを動的にリンクする方法は?一致するメソッドが見つかるまで、内部階層を上から検索しますか?ありがとう。 –

+1

@Summer_More_More_Tea質問をフリップ - なぜ*必要なのでしょうか?それがあなたが見ているクラスのメソッドなら、なぜVMはそれがオーバーライドされているかを知る必要がありますか? –

+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

残念ながら、あなたはバイトコードからそのことを知ることはできません。アノテーション@オーバーライドは唯一のアドバイザリです。必須ではありません。

JVMはメソッドを呼び出す5つの方法を定義しています。それらはinvokevirtual、invokeinterface、invokespecial、invokestaticおよび新しいinvokedynamicです。

invokevirtualに注目してください - これは最も一般的なディスパッチの形式で、ここで話している場合に使用されます。

invokevirtualが動作する方法は、実行時に、ディスパッチしているオブジェクトのクラスを調べることです。私たちが行っているメソッドの実装を見つけたら、それを呼び出します。そうでなければ、それはオブジェクトのクラスのスーパークラスを見て、やり直します。

バイトコードから、特定のメソッドがオーバーライドされているかどうかを確かめる方法はありません。親クラスのバイトコードを調べることはありません。

0

バイトコードは、コンパイル後に生成されます。したがって、オブジェクトがまだ作成されていないため、参照変数に基づいて呼び出されるメソッドのみが想定されます。

関連する問題