2

我在我的 WebApp 中使用了一些反射。我想做的是在做类型案例之后动态调用一个方法——这在编译时也不知道

这是我的代码的结构:

            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)给出的内容来转换它......

4

1 回答 1

5

我认为您对多态性的工作方式感到困惑。如果您需要知道要转换到的确切类,那将完全破坏多态性的全部目的。

即使您强制转换为BaseController-or 接口,正如 Jon Skeet 指出的那样,实际上更正确 - 实例将保持为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 回答