2

WebApp で少しの Reflexion を使用しています。私がやろうとしているのは、型のケースを実行した後にメソッドを動的に呼び出すことです-これもコンパイル時にわかりません

これが私のコードの構造です:

            Controller (Interface with one method called 'execute()')
                   |
                   |
                  \|/
             BaseController (Abstract Class with 1 abstr method called 'execute()')
              /         \
             /          _\|
            /            GetCarController extends BaseController
          |/_
         AddCarController extends BaseController

今、私は上記の構造を使用するこのコードを持っています:

  BaseController baseContr;

   Properties prop = new Properties();
   prop.load("some inputstream to config.properties");

    Constructor cons = Class.forName( prop.getProperty( keyProperty ) ).
    getConstructor( Class.forName( prop.getProperty( keyProperty ) ).getClass() );// keyProperty is some input string from user
   ( ( XXXXXX )cons.newInstance ( new Car(....) )  ).execute();

あなたが見XXXXXXているところは、実際に型キャストを動的に配置する方法が欲しいところです。execute()このキャストは、いずれかでメソッドを呼び出す方法を見つける必要があります。そうしないと、 メソッドを呼び出すために BaseController の実装のいずれかを直接使用したくありませんが、与えられたものに基づいてキャストする方法が必要AddCarControllerです ...GetCarControllerprop.getProperty(keyProperty)

4

1 に答える 1

5

ポリモーフィズムの仕組みを混乱させていると思います。キャスト先の正確なクラスを知る必要がある場合、それはポリモーフィズムの目的全体を完全に無効にします。

BaseControllerJon Skeet が指摘したように、 orにキャストしたとしても、実際にはより正確ですが、インスタンスはAddCarControllerorGetCarControllerインスタンスのままでありexecute()、このインスタンスを呼び出すとAddCarController#execute()orが呼び出されGetCarController#execute()never BaseController#execute()が呼び出されます。

この動作の例を次に示します。

class A {
    public void hello() {
        System.out.println("Hello from class A");
    }
}

class B extends A {

    @Override
    public void hello() {
        System.out.println("Hello from class B");
    }
}

public class Main {

    /**
     * @param args
     * @throws OperationNotSupportedException
     */
    public static void main(final String[] args) {
        final A a = new B();
        a.hello();
    }
}

"Hello from class B"期待どおりに印刷されます。


編集: リフレクションとインターフェイスを使用したより詳細な例:

class A implements I {

    @Override
    public void hello() {
        System.out.println("Hello from class A");
    }
}

class B implements I {

    @Override
    public void hello() {
        System.out.println("Hello from class B");
    }
}

interface I {
    public void hello();
}

public class Main {

    /**
     * @param args
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws OperationNotSupportedException
     */
    public static void main(final String[] args) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException {
        I i = (I) Class.forName("A").newInstance();
        i.hello();
        i = (I) Class.forName("B").newInstance();
        i.hello();
    }
}
于 2013-04-15T14:03:55.423 に答える