Java这种以啰嗦著称的编程语言,反射代码也很啰嗦。每次看到很多人使用原生的反射接口,我心里都在想,愚蠢的人类啊,为什么不封装一下再用。
能用到反射的场景
不能静态决定,比如根据URL参数的字符串调用相应方法的时候。
避免样板代码的时候,例如可以用反射代替,繁琐的JSON对象解析代码。
避免显式依赖的时候,有时候能用来打破项目之间的循环依赖关系。但要慎用,如果之间接口比较复杂,还是建议单独使用协议接口的方法。
访问私有成员,做一些黑科技的事情的时候。
方法调用封装
封装前的反射调用方法:
try { Class class = obj.getClass(); Method method = class.getDeclaredMethod("foo", new Class[] { String.class }); method.invoke(obj, new Object[] {"hi"});} catch (Exceptione ex) {}
非反射直接调用:
obj.foo("hi");
封装后的反射调用:
Reflection.callMethod(obj, "foo", "hi");
字段赋值封装
封装前的反射调用方法:
try { Class class = obj.getClass(); Field field = class.getDeclaredField("bar"); field.setAccessible(true); Object old = field.get(obj); field.set(obj, "hi"); return old;} catch (Exceptione ex) {}
非反射直接字段赋值:
obj.bar = "hi";
封装后字段赋值:
Reflection.setField(obj, "bar", "hi");
源码
Talk is cheap, show me the code.
这里是我简单的,不是很完整,只是解决了目前自己的需求。源码也就100行,自己看吧。
有Declared和无Declared的区别
在Class类接口中,getDeclaredMethod getDeclaredField和getMethod getField的区别。
带Declared的包含本类的私有和公开成员,不包含继承的成员。不带Declare不含继承的和自身的公开成员,不包含私有成员。如果要访问全体的成员,包括所有继承的和私有的,那么代码只会更加复杂。幸运的是Reflection类的封装已经帮你实现了。