(模擬Java內省的功能)
★ 準備工作
定義兩個Model類,裏面所有的屬性都是private的,然後爲每個屬性提供getter和setter方法;
再準備一個Map,map的key值都是類裏面的屬性字段的字符串表示,值任意。
★ 真正的工作
設計一個方法Object getModel(Map map,Class cls),傳入一個包含所有值的Map,然後再傳入Model類的class,那麼返回Model類的實例,這個實例裏面已經包含好了所有相關的數據。也就是把Map中的數據通過反射,設置回到Model類實例中。
Beanutils用了魔術般的反射技術!
需求分析:給你一個HashMap集合,將他直接封裝成相應的值對象!(聽起來很強!今天我們來看看他的底層代碼是如何實現的!)
UserModel值對象:
package cn.hncu.MyBeanUtils;
import java.io.Serializable;
public class UserModel implements Serializable{
private String uuid;
private String name;
private int age;
private String pwd;
public UserModel() {
super();
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserModel other = (UserModel) obj;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
@Override
public String toString() {
return uuid + ", " + name + ", " + age+", pwd:"+pwd;
}
}
BookModel值對象:
package cn.hncu.MyBeanUtils;
import java.io.Serializable;
public class UserModel implements Serializable{
private String uuid;
private String name;
private int age;
private String pwd;
public UserModel() {
super();
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserModel other = (UserModel) obj;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
@Override
public String toString() {
return uuid + ", " + name + ", " + age+", pwd:"+pwd;
}
}
MyBeanUtils工具類(我的BeanUtils工具類–利用底層代碼來實現apache公司中的一個BeanUtils工具類):
package cn.hncu.MyBeanUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
//一個很強的工具---能夠將map中的元素封裝成相對應的值對象!
public class MyBeanUtils {
//BeanUtils是阿帕奇公司的一個主要利用了類反射做出來的一個很強的工具!接下來我來把他的底層代碼給實現掉,看看他的強大之處在哪裏
//主要類中調用了populate()方法來實現功能代碼
//map是已經封裝好的HashMap集合,裏面的數據都是存在的,cls也是從已知值對象的方法名(例如:UserModel.class)
public static<T> T populate(Class<T> cls,Map<String, Object> map) throws Exception {
Object obj = cls.newInstance();//值對象必須規範(即值對象中必須有一個空參構造方法!)
//獲取cls中的所有屬性
Field flds[] = cls.getDeclaredFields();
//遍歷屬性值與map中的屬性值進行比較,看是否存在該屬性
for(Field fld:flds){
//拿到每個變量值(包括私有變量)進行與map中的key進行比較,看是否能夠找到相匹配的
Object value = map.get(fld.getName());
if(value == null){
//說明在map集合中找不到在值對象中與之相匹配的屬性值
System.out.println(fld.getName()+"不存在,爲空值!");
continue;
}
//如果存在則找到相應的setter方法進行設置值的操作(給屬性賦值的操作)
//拿到屬性值對應的方法名!!!!!很強的(這裏也就是設計模中提到的值對象模板規範的原因)
String methodName = "set"+fld.getName().substring(0, 1).toUpperCase()+fld.getName().substring(1);
//再通過方法名字加上屬性(成員變量)類型找到該屬性值設置屬性值的方法進行屬性設置
Method m = cls.getMethod(methodName, fld.getType());
m.invoke(obj, value);
}
return (T) obj;
}
}
Client演示類:
package cn.hncu.MyBeanUtils;
import java.util.HashMap;
import java.util.Map;
public class Client {
public static void main(String[] args) {
Map<String, Object> map = new HashMap<String, Object>();
//給map集合中添加元素---以後這種值直接從前臺頁面中通過getParameterMap()直接拿到整個集合對象
//模擬前臺頁面!!!!
map.put("uuid", "A001");
map.put("name", "Java");
map.put("age", 15);
//map.put("pwd", "1234");
//調用那個工具類,這裏首先演示我們自己寫的工具類---MyBeanUtils工具類
try {
UserModel user = MyBeanUtils.populate(UserModel.class, map);
System.out.println(user);
System.out.println("------------------");
BookModel book = MyBeanUtils.populate(BookModel.class, map);
System.out.println(book);
} catch (Exception e) {
e.printStackTrace();
}
}
}
代碼實現: