在Java中动态转换和调用

kho*_*oma 2 java reflection dynamic

我在WebApp中使用了一点Reflexion.我想要做的是在执行类型情况后动态调用一个方法 - 在编译时也不知道

这是我的代码的结构:

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

现在我有这个使用上述结构的代码:

  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();
Run Code Online (Sandbox Code Playgroud)

你看到XXXXXX的地方实际上是我想要一种动态放置类型转换的方法.这个转换必须找到一种方法来调用该execute()方法,AddCarController或者 GetCarController 我不想直接使用BaseController的任何一个实现来调用方法,而是有一种方法根据prop.getProperty(keyProperty)给出的方式来转换它...

m0s*_*it0 5

我认为你对多态性的工作原理感到困惑.如果你需要知道要投射的确切类,那将完全打败多态的整个目的.

即使你转向BaseController-or接口,正如Jon Skeet所指出的那样,实际上更正确 - 实例仍然是一个AddCarControllerGetCarController实例,并且execute()在这个实例中调用将调用AddCarController#execute()or GetCarController#execute(),而且永远不会 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

印刷品"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();
    }
}
Run Code Online (Sandbox Code Playgroud)