2017-02-17 30 views
3

有沒有辦法執行以下操作?檢查一個類是否存在(在同一個包中)並且它是否存在,檢查是否存在特定的方法,如果存在,調用它?Java:檢查一個類是否存在並調用一個特定方法(如果存在的話)

說,我有類X.在X類的一些方法,我要做到以下幾點:

if (class Y exists) { //Maybe use Class.forName("Y")? 
    if (Y has method a(String, String)) { 
    call Y.a("hello", "world"); 
    } 
} 

這種事可能嗎?這樣做是否合理?謝謝。

+0

無論是合理取決於您的要求。在大多數情況下,這是不合理的。在極少數情況下,它*是合理的,你很可能明白你在做什麼以及你爲什麼這樣做。 – Kayaman

回答

3

是這樣的薄g可能嗎?這樣做是否合理? 謝謝。

當然這是可能的。
如果您開發一個程序或庫,必須動態地發現一些類,這是一個非常合理的事情。
如果不是這種情況,那不可能。


如果您的需要合理,您應該問您一個額外的問題:您是否應該調用靜態方法或實例方法?

下面是兩種溶液的樣品例如:

ReflectionClass包含邏輯使用反射:

import java.lang.reflect.Method; 

public class ReflectionCalls { 
    public static void main(String[] args) { 
     new ReflectionCalls(); 
    } 

    public ReflectionCalls() { 
     callMethod(true); 
     callMethod(false); 
    } 

    private void callMethod(boolean isInstanceMethod) { 

     String className = "DiscoveredClass"; 
     String staticMethodName = "methodStatic"; 
     String instanceMethodName = "methodInstance"; 
     Class<?>[] formalParameters = { int.class, String.class }; 
     Object[] effectiveParameters = new Object[] { 5, "hello" }; 
     String packageName = getClass().getPackage().getName(); 

     try { 
      Class<?> clazz = Class.forName(packageName + "." + className); 

      if (!isInstanceMethod) { 
       Method method = clazz.getMethod(staticMethodName, formalParameters); 
       method.invoke(null, effectiveParameters); 
      } 

      else { 
       Method method = clazz.getMethod(instanceMethodName, formalParameters); 
       Object newInstance = clazz.newInstance(); 
       method.invoke(newInstance, effectiveParameters); 

      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

DiscoveredClass(我們在示例操作類)

package reflectionexp; 

    public class DiscoveredClass { 

     public static void methodStatic(int x, String string) { 
      System.out.println("static method with " + x + " and " + string); 
     } 

     public void methodInstance(int x, String string) { 
      System.out.println("instance method with " + x + " and " + string); 
     } 

    } 

輸出:

實例方法有5個招呼

與5靜態方法和Hello

+0

看起來不錯,尤其是展示如何調用靜態和非靜態方法。謝謝! – HikeTakerByRequest

+0

偉大的,如果它可以幫助你。不用謝 :) – davidxxx

1

您可以使用Class.forName

try { 
    Class yourClass = Class.forName("classname"); 
    Object o = yourClass.newInstance(); 
} catch(ClassNotFoundException e) { 
    //Throw error or whatever 
} 

要檢查方法存在,你可以在一個try/catch

2

是的,這是可以做到使用NoSuchMethodError e。我在與當前類相同的包中創建了一個Test類。

import java.lang.reflect.Method; 

public class Sample { 

    public static void main(String[] args) { 
     Class<?> clazz = null; 
     try { 
      clazz = Class.forName("Test"); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if (clazz == null) { 
      System.out.println("class not found. Go eat some waffles and correct the name"); 
      return; 
     } 

     Method m = null; 
     try { 
      m = clazz.getMethod("foo", null); 
     } catch (NoSuchMethodException | SecurityException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     if (m == null) { 
      System.out.println("method not found. Go eat some waffles and correct the name"); 
      return; 
     } 
     Test t; 
     try { 
      t = (Test) clazz.newInstance(); 
      m.invoke(t, null); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


    } 

} 

public class Test { 

    static { 
     System.out.println("test..."); 
    } 

    public void foo() { 
     System.out.println("foo"); 
    } 
} 

O/P:

test... 
foo 
+0

大部分情況是有道理的,但在這種情況下,我們不能強制類類型測試,因爲它可能不存在,不是嗎?如在,這個代碼不會編譯我認爲。 – HikeTakerByRequest

1

爲此,您可以使用反射,但它不是真正實用,除非你想這可能不會出現在運行時,或者如果你正在嘗試訪問類訪問私人或隱藏的字段。下面的例子。

public static void reflectionDemo(){ 

    //Here we attempt to get the common URI class 
    //If it is found, we attempt to get the create method 
    //We then invoke the create method and print the class name of the result. 

    try { 
     Class<?> uriClass = Class.forName("java.net.URI"); 
     //getMethod(String name, Class<?>... args); 
     java.lang.reflect.Method create = uriClass.getMethod("create", String.class); 

     //The first parameter is null because this is a static method. 
     //invoke(Object target, Object... args); 
     System.out.println(create.invoke(null, "some/uri").getClass()); 
     //Will print class java.net.URI 

    } catch (ClassNotFoundException e) { 
     // If class doesnt exist 
     e.printStackTrace(); 
    } catch (NoSuchMethodException e) { 
     // If method doesnt exist 
     e.printStackTrace(); 
    } catch (SecurityException e) { 
     // See Javadoc 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) { 
     // From invoke 
     e.printStackTrace(); 
    } catch (IllegalArgumentException e) { 
     // From invoke 
     e.printStackTrace(); 
    } catch (java.lang.reflect.InvocationTargetException e) { 
     // From invoke 
     e.printStackTrace(); 
    } 
} 
0

爲了找到一個類是否存在,你可以使用的forName()方法的類。 要查找某個方法是否存在,可以在Class上使用getMethod()方法。 文檔瀏覽:

https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String) https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getMethod(java.lang.String,%20java.lang.Class...)

對於類的問題,你想使用類似的代碼:

try { 
    Class.forName("Y"); 
} 
catch (ClassNotFoundException e) { 

} 

對於你的方法的問題是,你要使用如下代碼:

try { 
    Class.getMethod(a); 
} 
catch (NoSuchMethodException e) { 

} 
相關問題