现在有一个场景: 有一个方法,他的作用是接收命令(字符串类型的)和该命令对应的参数。 这样的命令有N多个。这样的一个方法怎么实现? 按照传统的面向过程的思维:字符串操作截取出命令的String值。根据String的值。写出N多个if else if else 例如这样:
if(命令字1){
fun();
}
else if(命令字2){
fun();
}
...
...
如上就陷入了面向过程的思维。 那么如何使用java的反射 去优化这样的代码结构。 先说下思路:
- 利用java的反射 根据外部传入的不同的命令字,去动态的获取对应的class。再根据该class去创建对象。调用对象的方法,也可给对象赋值。动态的保存数据
- 编写一个抽象类 让所有命令字对应的bean去继承。在抽象类中实现公共方法,如有需要也可声明方法,让bean去分别实现 利用如上的思路就可以避开N多个 if else if else if else if
举个实际栗子: 创建一个bean 来保存命令的对应内容
public class ReflectBean extends SuperDemo {
private String name;
private int age;
public void getAge(){
System.out.println("getAge():"+this.Age);
}
public void getName(){
System.out.println("getName():"+ this.name);
}
public Demo1class(String name, int age) {
this.name = name;
this.age = age;
System.out.println("111111构造 函数被调用了 哈哈哈哈");
}
@Override
public String toString() {
return "ReflectBean{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
再创建个superDemo
public abstract class SuperDemo {
//父类的方法 子类的公共方法哈
public void superDemo(){
System.out.println("wo shi super demo de fuc");
}
}
好了,如上 bean和对应的父类都创建好了。 接下来就开始反射了。 具体代码如下:
public class ReflectUtils {
public static Object getObjectByString(String className) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException {
//com.cn.reflectdemo.createobjectbystring.beans 类的包路径
className = "com.cn.reflectdemo.createobjectbystring.beans." + className;
//获取名字为className的class
Class clazz = Class.forName(className);
//获取指定参数类型的构造函数,这里传入我们想调用的构造函数所需的参数类型
Class[] classes = new Class[]{String.class, int.class};
Constructor constructor = clazz.getConstructor(classes);
Object object = constructor.newInstance("www", 22);
//调用对象的方法
// 调用ReflectBean类中的getAge方法
Method method = clazz.getMethod("getAge");
method.invoke(object);
//调用 getName的方法
method = clazz.getMethod("getName");
method.invoke(object);
//调用父类的方法
method = clazz.getMethod("superDemo");
method.invoke(object);
// 设置成员变量的值
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
f.set(object, 33);
System.out.println(object.toString());
//json 字符串 赋值给bean
//应用场景:外部json string 数据传递到服务端,服务端解析 保存
String jsonbody = "{\"name\":\"yyyy\", \"age\":444}";
// json转map
Map<String, String> map = new LinkedHashMap<>();
map = JSON.parseObject(jsonbody, LinkedHashMap.class);
Field[] fields = clazz.getDeclaredFields();
// 转换为有下标的集合
List<String> list = new ArrayList<>();
for (String key : map.keySet()) {
list.add(map.get(key));
}
for (int i = 0; i < list.size(); i++) {
//private属性设置可访问权限
fields[i].setAccessible(true);
fields[i].set(object, list.get(i));
}
System.out.println(object.toString());
return "";
}
public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException {
ReflectUtils.getObjectByString("ReflectBean");
}
如上 在实际开发中代码就显非常高大上了。 我们的口号是什么:写出别人看不懂的代码。