Java、反射、从类获取方法

Java、反射、从类获取方法,java,reflection,Java,Reflection,我在Java中使用反射时遇到一些问题。我试图保存一个数据结构的方法,但得到一个错误。错误是 java.lang.NoSuchMethodException:cs671.eval.SerialList.addjava.lang.Integer,java.lang.String 在本例中,我尝试获取的方法是一个SerialList的add方法,该方法将Comparable和Object作为其参数 structType=cs671.eval.SerialList、keyType=java.lang.

我在Java中使用反射时遇到一些问题。我试图保存一个数据结构的方法,但得到一个错误。错误是

java.lang.NoSuchMethodException:cs671.eval.SerialList.addjava.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方法这些类comparableClass和objectClass是正确的

提前谢谢

添加:这是SerialList的add方法签名 public void addjava.lang.Comparable,java.lang.Object-

在本例中,我尝试获取的方法是一个SerialList的add方法,该方法将Comparable和Object作为其参数

但是传递类-java.lang.Integer、java.lang.String

请注意-对于非public的getMethod,只有public方法是可见的。您必须使用getDeclaredMethod来代替它。

您是说-

在本例中,我尝试获取的方法是一个SerialList的add方法,该方法将Comparable和Object作为其参数

但是传递类-java.lang.Integer、java.lang.String

请注意-对于非public,只有public方法对getMethod可见。您必须改用getDeclaredMethod。

来源:

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

=>您需要从以下位置传递java.lang.Compariable.class和java.lang.Object.class

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


=>您需要传递java.lang.Compariable.class&java.lang.Object.class

对之前提供的错误答案表示歉意。根据您的评论,您似乎试图通过避免在该方法的签名中提供所需的特定参数类型来获得该方法

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

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

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

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

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

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

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

ApacheCommonsBeanUtils中已经有这样的功能,特别是在和中


上述方法的源代码可以很容易地在线查看。

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

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

ApacheCommonsBeanUtils中已经有这样的功能,特别是在和中


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

cs671.eval.SerialList.add的签名是什么?您是否尝试过运行Class.getMethods并打印名称/参数类型列表?例如,如果SerialList扩展了ArrayList,则Add方法实际上是addint,Object。@Polygenme:将签名添加到post。@Sbodd:我编写的Add方法不是
尝试获取时,需要一个可比较的and对象,而且SerialList不会扩展任何内容。cs671.eval.SerialList.add的签名是什么?您是否尝试过运行Class.getMethods并打印名称/参数类型列表?例如,如果SerialList扩展了ArrayList,那么Add方法实际上将是addint,Object。@PolyMone:将签名添加到post。@Sbodd:我编写了我试图获取的Add方法,它使用了一个可比较的and对象,SerialList也不会扩展任何内容。这些类,Integer和String,是稍后将在代码中传递到add方法的对象类。我通过读取类名、创建它们的类实例并将这些类实例传递到getMethod中来检索它们。但是getMethod需要一个可比较的and对象。我需要知道如何使用这两个类告诉getMethod它们是正确的,因为整数将是一个可比较的对象,字符串将是一个object object.Compariable.class和object.class。我不想硬编码它们,因为稍后可以使用不同的签名检索不同的方法。以及add方法是公共的。问题是,要实现这一点,您需要事先知道方法签名。这些类,Integer和String,是稍后将在代码中传递到add方法的对象类。我通过读取类名、创建它们的类实例并将这些类实例传递到getMethod中来检索它们。但是getMethod需要一个可比较的and对象。我需要知道如何使用这两个类告诉getMethod它们是正确的,因为整数将是一个可比较的对象,字符串将是一个object object.Compariable.class和object.class。我不想硬编码它们,因为稍后可以使用不同的签名检索不同的方法。以及add方法是公共的。问题是您需要事先知道方法签名才能实现这一点。