0

この 1 時間か 2 時間は、Java リフレクションに飛び込んできました。ちゃんと理解できるようになったと思います。

しかし、探していたいくつかの答えを見つけることができませんでした。

私が理解したのは、リフレクションがクラス ルックアップから大きな (最大の?) パフォーマンス ヒットを受けるということです。

2 つの質問があります。

現在のコンテキスト内からメソッドを呼び出すにはどうすればよいですか (それは可能ですか?)? また、現在のコンテキスト内で呼び出すと、クラス ルックアップによるパフォーマンス ヒットは相殺されますか?

例えば:

class User {
   private String name;

   public getName(){ return name; }
   public setName(String name){ this.name = name; }

   public void doSomething() {
       //some random stuff
       //I would like this method to invoke randomMethod();
       //Since it is within the same context(this)
       //Will this reduce the performance cost?

       //Please assume from my goals that I will ALWAYS know the name of the method i                  want to call.
      //So I wont need to loop through all available methods.

   }

   public void randomMethod() {

   }
}

ある種のディスパッチャーを実現しようとしています。たとえば、Java での Web 開発の場合です。

フレームワークなどには興味がありません。

したがって、ユーザーが URL http://www.hiurl.com/home/indexを入力すると

ホームはコントローラーで、アクション (リフレクションによって呼び出されるメソッド名) にインデックスを付けます。

失敗する可能性が多いことを除けば、これを絶対に避けるべき理由がある場合は、私にも知らせてください.

私の質問が明確であることを願っています。お時間を割いてお読みいただきありがとうございます。返信をお待ちしております。

4

4 に答える 4

3

いいえ、残念ながら、すべてが同じインスタンスで実行されたとしても、リフレクションを介して後続のメソッド呼び出しを最適化することはできません。この理由は基本的に、呼び出しのためのリフレクション メソッドのシグネチャです。

// in java.lang.reflect.Method
Object invoke(Object instance, Object... args);

// in java.lang.reflect.Field
Object get(Object instance)

リフレクションを使用して呼び出しを最適化するためにできる唯一のことは、呼び出しごとのコストのかかるルックアップを避けるためにMethodField、などへの参照を格納することです。Constructor

public class User {

    public void methodToBeCalledUsingReflection() {
        // some logic
    }

    public void invocationWithPerformanceHit() {
        // lookup of Method instance - costly operation!
        Method method = User.class.getMethod("methodToBeCalledUsingReflection");
        // actual invocation of method
        method.invoke(this);
    }

    public void invocationWithoutPerformanceHit() {
        // only actual invocation of method
        method.invoke(this);
    }

    // moving Method instance to static field which is initialized (looked up) only once
    public static final Method method = getMethodReference("methodToBeCalledUsingReflection");

    private static Method getMethodReference(String methodName) {
        try {
            return User.class.getMethod(methodName);
        } catch(Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

それに加えて、パフォーマンスを妨げ、型安全性が低く、その他の欠点があるため、非常に正当な理由がある場合にのみリフレクションを使用することをお勧めします。リフレクションなしで行けるのであれば、それを使用すべきではありません。

于 2012-06-26T08:53:34.780 に答える
2

あなたが正しく理解している場合、特定の文字列に対してコードのさまざまな部分を実行したいと考えています。

コードの可読性が向上するという理由だけで、これを行うより「通常の」方法がある場合は、リフレクションを避ける必要があると思います。

戦略パターンのようなものを使用することを考えてください。あなたの場合はうまくいくはずです。

于 2012-06-26T08:37:57.923 に答える
1

コントローラーメソッドへのディスパッチだけを行っている場合は、パフォーマンスについてまったく心配する必要はありません。リフレクションの遅さの全体的な問題は、メソッドを直接呼び出すために必要な 1ns と、ルックアップ + 呼び出しに必要なおそらく 100ns を比較する場合です。ところで、私は Strategy パターンへのリフレクションを好みますが、これら 2 つは実際には非常に近いので、それはあなたの判断です。

于 2012-06-26T09:19:17.467 に答える
0

メソッドを呼び出すコンテキストの種類に違いはありません。すべての場合で、同じ方法で呼び出します。メソッドを呼び出すには、「this」オブジェクトを渡す必要があります。

見てください:http ://www.java2s.com/Code/Java/Reflection/CallamethoddynamicallyReflection.htm

于 2012-06-26T08:41:26.547 に答える