没有做任何修改前:名字:富贵;颜色:黑色
哈哈,机智如我,怎么能被这种问题打到,从代码中可以看到我们使用了构造器的newInstance方法实例化了一个HaShiQi对象。
代码:con.newInstance();
是不是很熟悉?,在文章JAVA设计模式-动态代理(Proxy)源码分析中,实例化代理类对象的时候,也使用到了:
// 通过反射,将h作为参数,实例化代理类,返回代理类实例。
return cons.newInstance(new Object[]{h});
接下来就是访问对象的属性和方法了如果我们把所有的属性和方法都访问到,不就把同事的狗狗看了一遍了吗?。
八,修改属性
// 修改狗狗的颜色 // 获取狗狗的color属性 Field filed = clazz.getField("color"); filed.set(haShiQi, "红色"); System.out.println("修改狗狗的颜色:"+haShiQi.toString());打印结果:
没有做任何修改前:名字:富贵;颜色:黑色
修改狗狗的颜色:名字:富贵;颜色:红色
修改成功,接着修改狗狗的名字:
// 修改狗狗的颜色
// 获取狗狗的color属性
Field filed = clazz.getField("color");
filed.set(haShiQi, "红色");
System.out.println("修改狗狗的颜色:"+haShiQi.toString());
// 修改狗狗的名字
filed = clazz.getDeclaredField("name");
// 强制设置为可以访问
filed.setAccessible(true);
filed.set(haShiQi, "惊喜");
System.out.println("修改狗狗的名字:"+haShiQi.toString());
打印结果:
没有做任何修改前:名字:富贵;颜色:黑色
修改狗狗的颜色:名字:富贵;颜色:红色
修改狗狗的名字:名字:惊喜;颜色:红色
修改成功,但是千万要注意是的是的getDeclaredField方法,而不是getField方法,使用getField方法会抛出异常:Exception in thread "main" java.lang.NoSuchFieldException: name;
同时filed.setAccessible(true);也是必不可少了,否则将抛出异常:Exception in thread "main" java.lang.IllegalAccessException: Class com.zcz.reflecttest.LookLook can not access a member of class com.zcz.reflecttest.HaShiQi with modifiers "private"
属性修改完,我们就开始调用方法吧。
九,调用方法
//调用run方法 Method method = clazz.getMethod("run"); method.invoke(haShiQi, null);打印结果:
惊喜 去跑着玩儿
调用成功;
代码:method.invoke(haShiQi, null);
是不是觉得这句代码也是很熟悉的?在文章JAVA设计模式-动态代理(Proxy)示例及说明中也有相同的用法:
// 通过反射机制,通知力宏做事情
method.invoke(object, args);
我们继续,eat方法和run方法一样,都是公有的方法,这里就不再演示了,接下来演示一下私有的dance方法:
打印结果:
惊喜 去跑着玩儿
惊喜 来跳一支舞
也同样成功了,但是也要注意getDeclaredMethod方法和method.setAccessible(true);
到这里,同事不让我看的狗狗,我通过java的反射机制从里到外的全部都看了一遍,不仅仅是看了一遍,我还给他的狗狗改了颜色和名字。调用了所有的方法。是不是很神奇,很有成就感?
十,总结
反射的基本用法已经都在上面的实例中演示到了,但是反射还是有其他的方法在这里并没有提到,有机会的话继续补充。
在上面的代码过程中,你也许也发现了,不仅仅是有类对象,而且还有属性,方法和构造器都是对象,属性是java.lang.reflect.Field类的对象,方法是java.lang.reflect.Method类的对象,构造器是java.lang.reflect.Constructor类的对象。看来在java中确实是一切皆对象。
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx