在很多常用的框架当中,比如SpringMVC,还有一些ORM框架,都是希望把数据包成一个Model,这样的话既直观,又能减少错误,今天就给大家讲解一下这些的底层实现原理。
首先要明白Java的反射机制
要掌握java新建对象的几种方式
然后如何通过反射获取属性和方法
最后如何通过反射去执行这些方法
这些将会将代码里一一展示
首先先新建一个普通的JavaBean,创建好setter和getter
public class Person {
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
然后就是核心代码
public class Main {
public static void main(String[]args){
Map map=new HashMap<String,Object>();
map.put("name","jack");
map.put("sex","female");
map.put("age",18);
//传入要最终转化的class和要转化的map
Person person =injectBean(Person.class,map);
System.out.println(person);
}
//使用泛型
public static final <T> T injectBean(Class<T> beanClass,Map parasMap) {
T bean = null;
try {
//通过反射生成对象
bean = beanClass.newInstance();
//还可以用Class.forName生成对象
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//获取类的方法
Method[] methods = beanClass.getMethods();
int len = methods.length;
for(int i = 0; i < len; ++i) {
Method method = methods[i];
String methodName = method.getName();
//如果方法名是set开头的且名字长度大于3的
if(methodName.startsWith("set") && methodName.length() > 3) {
//获取方法的参数类型
Class[] types = method.getParameterTypes();
//只有一个参数的方法才继续执行
if(types.length == 1) {
//取字段名且让其首字母小写
String attrName = firstCharToLowerCase(methodName.substring(3));
//map中是否有属性名
if(parasMap.containsKey(attrName)) {
Object value = parasMap.get(attrName);
try {
//通过反射的方式执行bean的mothod方法,在这里相当于执行set方法赋值
method.invoke(bean, new Object[]{value});
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
return bean;
}
//取字段名且让其首字母小写
public static String firstCharToLowerCase(String substring) {
if (substring!=null&& substring.charAt(0)>='A' && substring.charAt(0)<='Z'){
char[] arr = substring.toCharArray();
arr[0] = (char)(arr[0] + 32);
return new String(arr);
}else {
return substring;
}
}
}
代码的逻辑不难理解,主要是要掌握java的反射机制,我们通常还会将json转为model,有兴趣的朋友可以尝试着改写上面的代码来实现