在Java中动态转换和调用

时间:2013-04-15 13:54:14

标签: java dynamic reflection

我在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()AddCarController中的GetCarController方法    我不想直接使用BaseController的任何一个实现来调用方法,而是根据prop.getProperty(keyProperty)给出的方式来构建它...

1 个答案:

答案 0 :(得分:5)

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

即使你转向BaseController - 或接口,正如Jon Skeet所指出的那样,实际上更正确 - 实例仍将是AddCarControllerGetCarController个实例,在此实例中调用execute()将调用AddCarController#execute()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();
    }
}

按照预期打印"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();
    }
}