调用从字符串方法创建并实现实际方法参数

发布于 2024-10-16 18:47:57 字数 1767 浏览 1 评论 0原文

我有一个关于 method.invoke() 的问题。我正在使用以下代码构造方法:

public void exec(String property_name, Object value){
    try{
        Method method = some_class.getClass().
                getMethod("set"+property_name, new Class[] {
                                                  value.getClass()
                                              }
                         );
        method.invoke(some_class, value);
    }catch(Exception e){
        e.printStackTrace();
    }
}

我的 some_class 有方法:

public void setA(Test test){
     // do something
}

setA 函数的参数是接口,如下所示:

public interface Test{
     public void write(String str);
}

当我使用第一个示例代码中的 exec() 函数和 TestImpl(它是 Test 的实现)时,会引发异常,通知在 some_class 中找不到该方法。但是,当我将函数 exec() 与原始类一起使用而不是扩展或实现时,方法 exec() 工作正常。

我应该怎么做才能使方法与类的实现一起使用?

使用 SSCCE 进行更新,以防某些人需要 1:

public class test {
public static void main(String[] args) {
    exec("Name", new TestClassImpl());
}

public static void exec(String property_name, Object value){
    try{
        some_class sc = new some_class();
        Method method = sc.getClass().
                getMethod("set"+property_name, new Class[] {
                                                  value.getClass()
                                              }
                         );
        method.invoke(sc, value);
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

class some_class{
public some_class(){}
public void setName(TestClass test){
    System.out.println(test.name());
}
}

interface TestClass{
public String name();
}

class TestClassImpl implements TestClass{
public String name() {
    return "sscce";
}
}

提前致谢, 谢尔希。

I have a question regarding method.invoke(). I'm constructing method with following code:

public void exec(String property_name, Object value){
    try{
        Method method = some_class.getClass().
                getMethod("set"+property_name, new Class[] {
                                                  value.getClass()
                                              }
                         );
        method.invoke(some_class, value);
    }catch(Exception e){
        e.printStackTrace();
    }
}

My some_class has method:

public void setA(Test test){
     // do something
}

The parameter of the setA function is interface and looks like:

public interface Test{
     public void write(String str);
}

When I use exec() function from the first example code with TestImpl which is implementation of Test, exception is being raised, notifying that method not found in some_class. But when I use the function exec() with original class and not an extension or implementation, method exec() works fine.

What should I do for method to work with implementations of class?

Update with SSCCE in case it's needed by some1:

public class test {
public static void main(String[] args) {
    exec("Name", new TestClassImpl());
}

public static void exec(String property_name, Object value){
    try{
        some_class sc = new some_class();
        Method method = sc.getClass().
                getMethod("set"+property_name, new Class[] {
                                                  value.getClass()
                                              }
                         );
        method.invoke(sc, value);
    }catch(Exception e){
        e.printStackTrace();
    }
}
}

class some_class{
public some_class(){}
public void setName(TestClass test){
    System.out.println(test.name());
}
}

interface TestClass{
public String name();
}

class TestClassImpl implements TestClass{
public String name() {
    return "sscce";
}
}

Thanks in advance,
Serhiy.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

套路撩心 2024-10-23 18:47:57

问题在于 new Class[] { value.getClass() }。通过此方法,您可以搜索与参数类型具有完全相同的类的方法,但该方法不存在。

试试这个:

for (PropertyDescriptor prop : Introspector.getBeanInfo(some_class.getClass()).getPropertyDescriptors()) {
  if (prop.getName().equals(property_name)) {
    prop.getWriteMethod().invoke(some_class, value)
  }
}

或者只使用 Class.getMethods() 并搜索 setter 名称和一个参数。

The problem is the new Class[] { value.getClass() }. With this you search for a method with exactly the same class as parameter type, which does not exist.

Try this:

for (PropertyDescriptor prop : Introspector.getBeanInfo(some_class.getClass()).getPropertyDescriptors()) {
  if (prop.getName().equals(property_name)) {
    prop.getWriteMethod().invoke(some_class, value)
  }
}

or just use Class.getMethods() and search for setter name and one arg.

未蓝澄海的烟 2024-10-23 18:47:57

在一般情况下,这并不容易。您所了解的 Java 规范的某些部分甚至大多数编译器都无法完全正确。

在这种特殊情况下(只有一个参数),您基本上必须找到一种其参数类型与给定参数的类型兼容的方法。要么遍历参数类型的继承层次结构(不要忘记多个接口!),要么遍历具有一个参数和所需名称的类的所有方法并检查 paramType.isAssignableFrom(argType)。

Spring 中有一个实用程序类可能适合大多数情况:

http://springframework.cvs.sourceforge.net/viewvc/springframework/spring/src/org/springframework/util/MethodInvoker.java?view=markup#l210

(不确定这是否是该课程的最新版本。)

In the general case, this isn't easy. Your getting into parts of the Java spec that even most compilers don't get exactly right.

In this special case (exactly one parameter), you basically have to find a method whose parameter type is compatible with the type of the given argument. Either walk up the inheritance hierarchy of the argument type (don't forget multiple interfaces!), or go through all methods of the class that have one parameter and the required name and check paramType.isAssignableFrom(argType).

There's a utility class in Spring that probably gets it right for most cases:

http://springframework.cvs.sourceforge.net/viewvc/springframework/spring/src/org/springframework/util/MethodInvoker.java?view=markup#l210

(Not sure if this is the latest version of the class.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文