1

I'm having some trouble using reflection in Java. I'm attempting to save a method of a data structure but getting an error. The error is

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

The method, in this case, that I'm trying to get is the add method for a SerialList that takes a Comparable and an Object as its parameters.

structType = "cs671.eval.SerialList", keyType = "java.lang.Integer", and valType = "java.lang.String" are strings that were read in from a file.

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){}

Basically I'm trying to get the right method on the right datastructure with the correct classes that are going to get passed into that method but I don't know how to tell the getMethod method that those classes (comparableClass and objectClass) are the correct ones.

Thanks in advance!

Added: Here's the SerialList's add method signature public void add(java.lang.Comparable, java.lang.Object)

4

4 回答 4

5

你是说 -

在这种情况下,我试图获取的方法是 SerialList 的 add 方法,该方法将ComparableObject作为其参数。

但是通过课程 - java.lang.Integer, java.lang.String.


getMethod()只是一个注释 -对于您必须使用的非公众,只有公共方法是可见的getDeclaredMethod()

于 2013-06-21T20:35:14.057 回答
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 中发现了多个这样的方法,并且其中一个方法的返回类型比其他任何方法都更具体,则反映该方法;否则任意选择其中一种方法。

=> 你需要通过 java.lang.Comparable.class&java.lang.Object.class

于 2013-06-21T20:54:32.607 回答
0

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

但是,如果由于某种原因您在编译时不知道形参,那么您可以遍历类中的所有方法,直到找到适合您的参数的方法(或找到适合您的参数的最具体的方法) .

在 apache commons bean utils 中已经编写了执行此操作的功能,特别是在org.apache.commons.beanutils.MethodUtils.invokeMethod(...)MethodUtils.getMatchingAccessibleMethod(...)中。

上述方法的源代码可以在这里轻松地在线查看。

于 2013-06-21T21:36:03.790 回答
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
   }
}
于 2013-06-21T21:16:15.910 回答