Java,反射,从类中获取方法

时间:2013-06-21 20:29:19

标签: java reflection

我在Java中使用反射时遇到了一些麻烦。我试图保存数据结构的方法,但收到错误。错误是

java.lang.NoSuchMethodException: cs671.eval.SerialList.add(java.lang.Integer, java.lang.String)

在这种情况下,我想要获取的方法是SerialList的add方法,该方法将Comparable和Object作为其参数。

structType = "cs671.eval.SerialList"keyType = "java.lang.Integer"valType = "java.lang.String"是从文件中读取的字符串。

Class dataClass = null, comparableClass = null, objectClass = null;

try{ // create data structure
    dataClass = Class.forName(structType); 
    comparableClass = Class.forName(keyType);
    objectClass = Class.forName(valType);
}
catch(ClassNotFoundException e){}

java.lang.Object structObj = null;

try{ // Create a data structure object
    structObj = dataClass.newInstance();
}
catch(Exception e){}
Method m = null;
try{ // Attempt to get add method for the data structure
    m = dataClass.getMethod("add", comparableClass, objectClass); // This is where it fails
}
catch(Exception e){}

基本上我正在尝试在正确的数据结构上使用正确的类来获得正确的方法,这些类将被传递到该方法但我不知道如何告诉getMethod方法那些类(equivalentClass和objectClass)是正确的。

提前致谢!

补充:这是SerialList的add方法签名 public void add(java.lang.Comparable, java.lang.Object)

4 个答案:

答案 0 :(得分:5)

你说 -

  

在这种情况下,我想要获取的方法是SerialList的add方法,它以 Comparable Object 作为参数。< / p>

但是传递课程 - java.lang.Integerjava.lang.String


只需注意事项 - 对于您必须使用getMethod()的非公开者,getDeclaredMethod()只能看到公开方法。

答案 1 :(得分:1)

来自http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getMethod%28java.lang.String,%20java.lang.Class...%29

  

要在类C中查找匹配方法:如果C只声明一个具有指定名称且完全相同的形式参数类型的公共方法,那么这就是反映的方法。如果在C中找到多个这样的方法,并且这些方法中的一个具有比任何其他方法更具体的返回类型,则反映该方法;否则其中一种方法是任意选择的。

=&GT;您需要通过java.lang.Comparable.class&amp; java.lang.Object.class

答案 2 :(得分:0)

早些时候提供错误答案的道歉。根据您的评论,您似乎试图通过避免提供该方法签名中所需的特定参数类型来获取方法。

如果我的理解是正确的,那么您应该使用Class#getMethods()并检查返回的Method[]您的方法。考虑这样的骨架代码:

Method[] methods = dataClass.getMethods();
boolean matched = false;
// find a matching method by name
for (Method method: methods) {
   Class<?>[] parameterTypes = method.getParameterTypes();
   if ( "add".equals(method.getName()) && parameterTypes.length == 2 ) {
       // method is your target method 
       // however you'll need more strict checks if there can be another add method
       // in your class with 2 different parameter types
   }
}

答案 3 :(得分:0)

正如其他答案所述,要使用getMethod(),您需要知道并使用您尝试检索的方法的实际声明的形式参数。

但是,如果由于某种原因你在编译时不知道形式参数,那么你可以迭代类中的所有方法,直到找到适合你的参数的方法(或者找到最合适的方法)你的参数)。

在apache commons bean utils中已经编写了这样的功能,特别是在org.apache.commons.beanutils.MethodUtils.invokeMethod(...)MethodUtils.getMatchingAccessibleMethod(...)中。

可以在线查看上述方法的源代码here