请教一个 Java 反射与动态代理的问题:动态代理生成的对象通过反射设置报错

2020-10-20 00:23:21 +08:00
 cqdx02

比如定义了一个接口 IHello:

interface IHello {

	void printHello();
}

以及一个 User 类:

class User {

  IHello ihello;

  public User(){}

  public void setIHello(IHello hello){

    this.ihello = hello;
  }

  public void sayHello(){

    iHello.printHello();
  }

}

在实际调用时,采用动态代理先生产 IHello 的实例,然后设置到 User 对象中调用是可以的:

Ihello hello = (IHello) new DynamicProxy().bind(new Hello());

User user = new User();

user.setIHello(hello);

user.sayHello();

现在某些情况下,我要通过反射的方式设置 User 中的成员变量,我是这么写的:

Ihello hello = (IHello) new DynamicProxy().bind(new Hello());

User user = new User();

Class<?> parmeter = new Class[1];

parmeter[0] = hello.getClass();

// 获取方法时出错

Method setHello = user.getClass().getDeclaredMethod("setIHello", parmeter);

setHello.invoke(user,hello);

在上面一句获取方法时出错了,报错内容为 NoSuchMethodException,因为 parmeter 类型不对。

请教应该怎么改呢?

(上面那句改成 getDeclaredMethod("setIHello", IHello.class)肯定是可以的,问题是现在不希望指定类型,而希望 parmeter 是动态生成的)

1453 次点击
所在节点    程序员
7 条回复
JasonLaw
2020-10-20 07:18:18 +08:00
hello.getClass() != IHello.class
cqdx02
2020-10-20 08:42:44 +08:00
@JasonLaw 嗯嗯,那应该如何改呢?
JasonLaw
2020-10-20 08:48:42 +08:00
@cqdx02 #2 我希望你提供完整的代码,你贴出的代码不仅仅有错误、不完整,也不知道 DynamicProxy 到底是哪里来的。
cqdx02
2020-10-20 09:12:37 +08:00
@JasonLaw 好的,我只贴了报错的那部分,晚上回去补全下。
young1lin
2020-10-20 09:33:22 +08:00
你这样写肯定是错的啊,会不会用反射? IDEA 没提示?

parmeter[0] = hello.getClass();

// 获取方法时出错

Method setHello = user.getClass().getDeclaredMethod("setIHello", parmeter);
首先,你这获取的是具体的实体类,但是这里是要求你根据方法名和方法参数类型,来获得具体的方法对象句柄。你也可以理解为获得方法的定义,方法的外壳。

后面的 method.invoke 是传具体参数,如果你这里传的是 hello.getClass() 这里获取的是具体的类,比如 Hello.class,而不是 IHello.class 。

你可以打个断点看看到底是怎么回事,他就会去找 setIHello(Hello hello),而不是 setIHello(IHello iHello)方法,当然会报没有这样的方法的错误。你把这个

Method setHello = user.getClass().getDeclaredMethod("setIHello", parmeter);

parrmeter 改成 IHello.class 不就好了?

我建议你好好在 《 Java 编程思想》里面好好看看关于反射的那一章。
palmers
2020-10-20 09:38:55 +08:00
// 获取方法时出错

Method setHello = user.getClass().getDeclaredMethod("setIHello", parmeter);
palmers
2020-10-20 09:39:21 +08:00
@palmers 这句使用泛型约束是可以的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/716534

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX