2012-05-10 8 views
1

私は.classファイルを持っていて、クラス名、フィールドまたはメソッドを含む.classファイルについて何も知らない。私がする必要があることは、クラスに関するすべてを見つけ出し、クラスのオブジェクトをインスタンス化することです。オブジェクトをインスタンス化し、JAVAのリフレクションを使用して.classファイル経由でメソッドを呼び出すか?

getDeclareMethod()、getDeclareFields()およびgetDeclareConstructor()を呼び出した後で、.classファイルの内容についてはわかっていないことを覚えておいてください。String strのフィールドと、変数strと純粋なコンストラクタに名前を代入します。

したがって、オブジェクトをインスタンス化し、strにStringを割り当てるメソッドを呼び出す方法は問題ですか?私は、クラスまたはメソッドの宣言が同じファイルにあるときにそれを行う方法を知っていますが、これは未知の.classファイルです。私は皆さんに助けを求めます。

+2

これを継続的に行う必要がありますか? Bhavikが示唆するようにそれを逆コンパイルできますか?それとも、あなたが別の「未知の」クラスに何度も何度もやらなければならないことです。なぜあなたのクラスの詳細が分からないのですか?これらのクラスはどこから来たのですか? –

+1

+1グレッグ、これらのクラスはどこから来たのですか?それについて何も知らないのであれば、なぜそれを使いたいのですか? ;) – Nishant

+0

あなたの返事をありがとう。ああ、それは単なる割り当てです....教授はそうするように私たちに求めます。 –

答えて

0

.classファイルをjavaファイルに変換することができます。つまり、JADを使用して逆コンパイルしてから、javaファイルのソースを知ることができます。

あなたはthisリソースを取ることができ、さらに多くのGoogleを見つけることができます。

0

ちょうどすべてのあなたの答えを得るu'llこのチュートリアルで行く..

Using Java Reflection

リフレクションは、Javaプログラミング言語の機能です。それは実行中の Javaプログラムがそれ自身を調べたり "イントロスペクト"したり、プログラムの内部の プロパティを操作することを可能にします。たとえば、Javaクラスがすべてのメンバーの名前を で取得して表示することは可能です。

0

.classファイルがある場合は、独自のClassLoaderを記述し、defineClassを使用してClassインスタンスを作成できます。そこから、名前とコンストラクタを得ることができます。コンストラクタがnullの場合は、単にClassインスタンスに対してnewInstanceを実行します。そうでない場合は、コンストラクタをハントして、適切な引数をコンストラクタnewInstanceメソッドに渡す必要があります。

4

まず、.classファイルをClassオブジェクトに変換する必要があります。 URLClassLoaderでこれを行うことができます。

File classFileString classNameがあるとします。

try { 
    URLClassLoader classLoader = new URLClassLoader(new URL[]{classFile.toURI().toURL()}); 
    Class<?> clazz = classLoader.loadClass(className); 
} catch (Exception e) { 
    // something went wrong.. 
    e.printStackTrace(); 
} 

は今、あなたはClassオブジェクトに格納されているあなたのクラスファイルを持っているが、どのようにその型のオブジェクトを作成することができますから呼び出されるメソッドがありますか?この状況では、java.lang.reflectパッケージのJava reflectionが便利です。

は、あなたがあなたのClass<?>clazzという名前の変数に格納されているオブジェクト、メソッド名のString methodName、およびメソッドの引数のString toSetを持っていると仮定しましょう。

try { 
    Object instance = clazz.newInstance(); 
    Method method = clazz.getDeclaredMethod(methodName, String.class); 
    method.setAccessible(true); 
    method.invoke(instance, toSet); 
} catch (Exception e) { 
    // something went wrong.. 
    e.printStackTrace(); 
} 

メソッド名が不明な場合、あなたはどちらかの反射を介して行うことができますが、より安定的にバイトコードを使用することにより、メソッドのバイトコードを検査することによって行われており、それを識別する方法を作成する必要がありますので注意してくださいASMまたはBCELのような注入/修飾/分析ライブラリーを含む。BCELは2006年以来更新されていませんが、使用方法を学ぶ方が簡単だという私の個人的意見です。ただし、ASMははるかに高速であり、最新の状態です。

+0

なぜバイトコード注入アプローチが反射よりも「安定」であると言いますか? –

+0

クラスにオーバーロードされたメソッドやクラスのメソッド名が不明な場合は、使用するメソッドを動的に検出(または時間を節約するために記録するファイルを保存)する必要があります。たとえば、void a(String)およびvoid b(String)があります。どちらも同じシグネチャを持つため、リフレクションを使用してどちらが望ましいセッターであるかを判断することはできません。バイトコード解析の使用により、実行時に所望の方法を決定することができる。 – Vulcan

+1

ありがとうございます。関連するメモで、特に目的を特定のフィールドに設定する場合は、リフレクションを使用してフィールドを直接設定することができます(つまり、アクセサメソッドを使用しない)。 –

関連する問題