2013-04-15 33 views
2

我在WebApp中使用了一些Reflexion。我所試圖做的是做類型案件後動態調用一個方法 - 這也是不知道在編譯時在Java中動態轉換並調用

這裏是我的代碼的結構:

  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其實是我想辦法把類型轉換動態。此鑄造必須找到一種方法來調用方法AddCarControllerGetCarController 我不想使用BaseController的任何一個實現直接調用方法,而是有一種方法根據prop.getProperty(keyProperty)給出的方法進行投射。 ..

+6

你爲什麼不只是投放到接口:使用反射和接口的更詳細的例子嗎?一旦你構建了實例,你知道它實現了接口,你可以調用execute,對吧? –

+0

在運行時,Java將調用實現中的'execute()'方法,但在'Interface'中。但在編譯時它不會......等等,讓我看看......我會很快回複評論......我想試試 –

+0

我剛試過它......它不工作。 你知道,Java不能在基類/接口/摘要中執行一個方法,但它只在編譯期間檢查基類和子類中的一致性 –

回答

5

我認爲你混淆了多態如何工作。如果你需要知道準確的類,那麼這將完全失敗多態性的全部目的。

即使你投以BaseController -or接口,如喬恩斯基特,這實際上是更正確─,該實例仍將是AddCarControllerGetCarController實例,在這種情況下調用​​將調用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"爲exepected。


編輯

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(); 
    } 
} 
+0

是的,我可以理解,但問題是我想這樣做: 'A a =(someImplementation)b' 其中'someImplementation'通過反射/動態找出 –

+0

再次,您不需要通過反思找到'someImplementation'。 'b'應該是您通過反射創建的對象實例,並且應該是正確的類型。使用固定的'someInterface'而不是'someImplementation'。 – m0skit0

+0

我很抱歉,但我認爲是我無法正確解釋我的問題......但是如果您的代碼如上所述,如果我們不知道實現的className,那麼我們知道任何實現接口的接口必須執行「執行」方法... 所以我們不知道實現的名稱是'B' ... –