2013-12-18 16 views
0

有沒有辦法基於只有字符串名稱實例化一個類?我明白反思需要包名稱o全稱。但是如果給你:在Java中的反思,並試圖複製控制器/行動

/類名/方法名參數= X

,你撕開,除了成類似:

callClass(ClassName).callMethod(methodName).params(...)(在這種情況下.params()是法)

在PHP這非常容易。我明白,在Java中,如此簡單,因爲您需要該類的完全限定名稱,因爲軟件包允許您多次定義一個名稱,並且這種方法可能會導致一些嚴重的性能問題。

任何想法我怎麼能做到這樣的事情

+1

不,你需要完整的類名。否則,無法確定您想要的類別方法。 –

+1

同時檢查參與反射的各種類型的javadoc,即'Class'和'Method'。除非該方法是'static',否則您需要該類的一個實例來調用該方法。 –

回答

1

這種或那種方式,你需要一個完全合格的類名。

你可以按照慣例做到這一點 - 追加你的類名預定的包名稱(或假設默認包)

或者,你可以做一些類加載器的魔法來查找僅基於部分名稱的完整類名(假設名稱不含糊)。換句話說,您的類加載器會跟蹤所有加載的類,然後您可以使用您的部分名稱與這些類名匹配。儘管如此,這對大多數應用程序來說都是嚴重的問題。

0

正如@DNA之前回答的那樣,您總是需要一個完全合格的類名。然後是反思,這兩者都非常緩慢,並且需要全力應對。以番石榴爲例,你可以做這樣的事情:

public static void main(String[] args) throws Exception { 
    String myClassName = "App"; 
    String methodName = "method"; 
    Object[] params = {}; 
    ClassPath cp = ClassPath.from(ClassLoader.getSystemClassLoader()); 
    ImmutableSet<ClassPath.ClassInfo> cls = cp.getTopLevelClasses(); 

    for (ClassPath.ClassInfo cl : cls) { 
     if(cl.getSimpleName().equals(myClassName)) { 
      Class<?> clazz = cl.load(); 
      for (Method m : clazz.getMethods()) { 
       if(m.getName().equals(methodName)) { 
        Object instance = clazz.newInstance(); 

        // invoke method - prints Hello 
        m.invoke(instance, params); 
       } 
      } 
     } 
    } 
} 

public void method() { 
    System.out.println("Hello!!!"); 
} 

非常殘暴。拋出很多例外,你必須處理。如果你有一個更大的項目,使用這樣的東西將需要很長時間。