您的位置:首页 > 编程语言

【BeanUtils】自己写的一个BeanUtils-代码方法详解

2016-08-25 15:12 330 查看
转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自大学之旅_谙忆的博客

BeanUtils工具包是由Apache公司所开发,主要是方便程序员对Bean类能够进行简便的操作。

在这里,不讲解如何使用apache的BeanUtils工具,而是我们自己写底层,自己利用类反射来实现BeanUtils的功能。

需要先学习类反射!

通过给定bean对象的类,和封装的Map对象,返回出一个bean对象。

准备bean对象:

这里准备了User类和Book类:

User

package cn.hncu.domain;

/**
* @author 陈浩翔
*
* 2016-8-25
*/
public class User {
private String uuid;
private String name;
private int age;
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;
}
@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;
User other = (User) 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 "User [uuid=" + uuid + ", name=" + name + ", age=" + age + "]";
}

}


Book

package cn.hncu.domain;

/**
* @author 陈浩翔
*
* 2016-8-25
*/
public class Book {
private String uuid;
private String name;
private double inPrice;
private double outPrice;
private int num;
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 double getInPrice() {
return inPrice;
}
public void setInPrice(double inPrice) {
this.inPrice = inPrice;
}
public double getOutPrice() {
return outPrice;
}
public void setOutPrice(double outPrice) {
this.outPrice = outPrice;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
@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;
Book other = (Book) 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 "Book [uuid=" + uuid + ", name=" + name + ", inPrice=" + inPrice
+ ", outPrice=" + outPrice + ", num=" + num + "]";
}
}


过度版的:

先看过度版的:接参后需要强转成对应的bean,因为返回类型是Object。

MyBeanUtils1

package cn.hncu.beanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class MyBeanUtils1 {

public static Object populate(Class cls ,Map map) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
Object obj = null;

//1、用类反射new出对象
obj = cls.newInstance();

//2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置
//2.1遍历出所有该类声明的属性
Field flds[] = cls.getDeclaredFields();//getDeclaredFields()返回Class中所有的字段,包括私有字段;
for(Field fld:flds){
//获取该fld对象所代表的属性名
String fldName = fld.getName();
//根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值
Object value = map.get(fldName);
if(value==null){//如果map中不存在对应的属性数据,我们在这里给出提示信息
System.out.println(fldName+"的数据为空");
}else{
//如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字
String mothodName = "set"+fldName.substring(0, 1).toUpperCase()+fldName.substring(1);

//根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象
Class paramTypes[] = new Class[1];
paramTypes[0] = fld.getType();
Method method = cls.getDeclaredMethod(mothodName, paramTypes);

//调用该method对象所代表的方法
Object args[] = new Object[1];
args[0]=value;
method.invoke(obj, args);
}
}
return obj;
}

}


测试

@Test
public void test1() {
Map map = new HashMap();
map.put("uuid", "001");
map.put("name", "Jack");
map.put("age", 20);

Map map2 = new HashMap();
map2.put("uuid", "001");
map2.put("name", "红楼梦");
map2.put("inPrice", 20.5);
//数据可能不全
map2.put("num", 123);
try {
User user =  (User) MyBeanUtils1.populate(User.class, map);
System.out.println(user);
Book book =  (Book) MyBeanUtils1.populate(Book.class, map2);
System.out.println(book);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}


测试结果:



这个还不是很完善,为什么呢,因为返回类型是Object,每次都要强转,比较麻烦,而且我们传了bean的class对象过去了,完全可以实现不用强转的,这个时候我们就需要用到泛型了。

而且Map的泛型我们可以确定了,肯定是
Map<String,Object>
这样的

好了,学习一下最终版的、

最终版:

MyBeanUtils

package cn.hncu.beanUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class MyBeanUtils {

public static<T> T populate(Class<T> cls ,Map<String, Object> map) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException{
T obj = null;

//1、用类反射new出对象
obj = cls.newInstance();

//2 再用类反射对新new的对象设置属性值(必须遵守Java设置规范)--即通过setter方法设置
//2.1遍历出所有该类声明的属性
Field flds[] = cls.getDeclaredFields();//getDeclaredFields()返回Class中所有的字段,包括私有字段;
for(Field fld:flds){
//获取该fld对象所代表的属性名
String fldName = fld.getName();
//根据属性名,到map中去读取数据,只有数据非空才需要给该属性设置值
Object value = map.get(fldName);
if(value==null){//如果map中不存在对应的属性数据,我们在这里给出提示信息
System.out.println(fldName+"的数据为空");
}else{
//如果map中存在对应的属性数据,则由属性名得出它的setter方法的名字
String mothodName = "set"+fldName.substring(0, 1).toUpperCase()+fldName.substring(1);

//根据方法名和参数的数据类型(其实就是属性的类型),获得Method对象
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = fld.getType();
Method method = cls.getDeclaredMethod(mothodName, paramTypes);

//调用该method对象所代表的方法
Object args[] = new Object[1];
args[0]=value;
method.invoke(obj, args);
}
}
return obj;
}

}


测试方法:

@Test
@SuppressWarnings("unchecked")
public void test() {
Map<String, Object> map = new HashMap();
map.put("uuid", "001");
map.put("name", "Jack");
map.put("age", 20);

Map<String, Object> map2 = new HashMap();
map2.put("uuid", "001");
map2.put("name", "红楼梦");
map2.put("inPrice", 20.5);
//数据可能不全
map2.put("num", 123);
try {
User user = MyBeanUtils.populate(User.class, map);
System.out.println(user);
Book book = MyBeanUtils.populate(Book.class, map2);
System.out.println(book);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}


测试结果:



完整项目源码链接:

–>点击访问本系列源码–

转载请注明出处:http://blog.csdn.net/qq_26525215

本文源自大学之旅_谙忆的博客
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐