利用反射实现单值和级联操作
单值操作
使用反射快速赋值,不涉及级联(如:ball.name)。
public class TestSimpleJava {
public static void main(String[] args) {
BasketBall basketBall = ObjectFactory.getInstance(BasketBall.class, InputData.testInput());
System.out.println(basketBall);
}
}
class InputData {
public static Map<String, String> testInput() {
Map<String, String> map = new HashMap<>(15);
map.put("name", "篮球");
map.put("brand", "乔丹");
map.put("price", "199");
map.put("buyCount", "5");
map.put("produce", "100");
map.put("testTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return map;
}
}
class ObjectFactory<T> {
private ObjectFactory() {
}
public static <T> T getInstance(Class<?> clazz, Map<String, String> map) {
Object object = null;
try {
object = clazz.getDeclaredConstructor().newInstance();
BeanUtil.setValue(object, map);
} catch (Exception e) {
e.printStackTrace();
}
return (T) object;
}
}
class BeanUtil {
private BeanUtil() {
}
public static void setValue(Object object, Map<String, String> value) {
Iterator<Map.Entry<String, String>> iterator = value.entrySet().iterator();
while (iterator.hasNext()) {
//获取当前数据
Map.Entry<String, String> entry = iterator.next();
try {
//根据传入的key获取属性和类型
Field field = object.getClass().getDeclaredField(entry.getKey());
//获取setter方法
Method methodSet = object.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(entry.getKey()), field.getType());
//解除封装
methodSet.setAccessible(true);
//导入数据
methodSet.invoke(object, isType(field, entry.getValue()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static Object isType(Field field, String value) throws ParseException {
String fileType = field.getType().getName();
String simpleDateFormat = null;
if (String.valueOf(String.class.getName()).equalsIgnoreCase(field.getType().getName())) {
return value;
}
if (String.valueOf(int.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Integer.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Integer.parseInt(value);
} catch (Exception e) {
return 0;
}
}
if (String.valueOf(double.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Double.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Double.parseDouble(value);
} catch (Exception e) {
return 0.0;
}
}
if (String.valueOf(long.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Long.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Long.parseLong(value);
} catch (Exception e) {
return 0;
}
}
if (String.valueOf(Date.class.getName()).equalsIgnoreCase(fileType)) {
if (value == null || "".equals(value)) {
return null;
} else {
Date date = null;
String regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+";
if (value.matches(regex)) {
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(value);
} catch (Exception e) {
return null;
}
return date;
}
regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+ \\d{1,2}+:\\d{1,2}+:\\d{1,2}+";
if (value.matches(regex)) {
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
} catch (Exception e) {
return null;
}
return date;
}
}
}
return null;
}
结果:
BasketBall{name='篮球', brand='乔丹', price=199.0, buyCount=5, produce=100, testTime=Sun Mar 08 23:54:34 CST 2020, ball=null}
级联操作
使用反射快速给关系类赋值(必须先进行实例化操作)。
public class TestSimpleJava {
public static void main(String[] args) {
BasketBall basketBall = ObjectFactory.getInstance(BasketBall.class, InputData.testInput());
System.out.println(basketBall);
System.out.println(basketBall.getBall().toString());
System.out.println(basketBall.getBall().getCreateCompany());
}
}
class InputData {
public static Map<String, String> testInput() {
Map<String, String> map = new HashMap<>(15);
map.put("name", "篮球");
map.put("brand", "乔丹");
map.put("price", "199");
map.put("buyCount", "5");
map.put("produce", "100");
map.put("testTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
map.put("ball.name", "球");
map.put("ball.createCompany.companyName", "篮球公司");
return map;
}
}
class ObjectFactory<T> {
private ObjectFactory() {
}
public static <T> T getInstance(Class<?> clazz, Map<String, String> map) {
Object object = null;
try {
object = clazz.getDeclaredConstructor().newInstance();
BeanUtil.setValue(object, map);
} catch (Exception e) {
e.printStackTrace();
}
return (T) object;
}
}
class BeanUtil {
private BeanUtil() {
}
public static void setValue(Object object, Map<String, String> value) {
Iterator<Map.Entry<String, String>> iterator = value.entrySet().iterator();
Object currentObject = null;
while (iterator.hasNext()) {
//获取当前数据
Map.Entry<String, String> entry = iterator.next();
try {
String fieldData = null;
//重置currentObject,每次循环都换成Object(BasketBall)
currentObject = object;
//判断是否有带.的数据
if (entry.getKey().contains(".")) {
fieldData = entry.getKey().substring(entry.getKey().lastIndexOf(".") + 1);
//根据.进行分割
String[] splitType = entry.getKey().split("\\.");
//object包含类的数据赋给currentObject
currentObject = object;
for (int i = 0; i < splitType.length - 1; ++i) {
//每次刷新获取类的数据,第一次查询BasketBall类get数据,第二次刷新获取Ball类的get数据
Method methodGet = currentObject.getClass().getDeclaredMethod("get" + StringUtil.toUpperCaseString(splitType[i]));
//第一次在BasketBall获取getBall()数据,第二次获取Ball类的getCreateCompany()数据
Object obj = methodGet.invoke(currentObject);
if (obj == null) {
//根据currentObject获取splitType[i]数据
Field field = currentObject.getClass().getDeclaredField(splitType[i]);
//解锁(解除封装)
field.setAccessible(true);
//根据currentObject的数据更新获取set数据
Method methodSet = currentObject.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(splitType[i]), field.getType());
//obj是变动的,第一次为Ball实例,第二次为CreateCompany的数据
obj = field.getType().getDeclaredConstructor().newInstance();
methodSet.invoke(currentObject, obj);
}
//刷新currentObject的值
currentObject = obj;
}
} else {
fieldData = entry.getKey();
}
//根据传入的key获取属性和类型
Field field = currentObject.getClass().getDeclaredField(fieldData);
//获取setter方法
Method methodSet = currentObject.getClass().getDeclaredMethod("set" + StringUtil.toUpperCaseString(fieldData), field.getType());
//解除封装
methodSet.setAccessible(true);
//导入数据
methodSet.invoke(currentObject, isType(field, entry.getValue()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static Object isType(Field field, String value) throws ParseException {
String fileType = field.getType().getName();
String simpleDateFormat = null;
if (String.valueOf(String.class.getName()).equalsIgnoreCase(field.getType().getName())) {
return value;
}
if (String.valueOf(int.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Integer.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Integer.parseInt(value);
} catch (Exception e) {
return 0;
}
}
if (String.valueOf(double.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Double.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Double.parseDouble(value);
} catch (Exception e) {
return 0.0;
}
}
if (String.valueOf(long.class.getName()).equalsIgnoreCase(fileType) || String.valueOf(Long.class.getName()).equalsIgnoreCase(fileType)) {
try {
return Long.parseLong(value);
} catch (Exception e) {
return 0;
}
}
if (String.valueOf(Date.class.getName()).equalsIgnoreCase(fileType)) {
if (value == null || "".equals(value)) {
return null;
} else {
Date date = null;
String regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+";
if (value.matches(regex)) {
try {
date = new SimpleDateFormat("yyyy-MM-dd").parse(value);
} catch (Exception e) {
return null;
}
return date;
}
regex = "\\d{4}+-\\d{1,2}+-\\d{1,2}+ \\d{1,2}+:\\d{1,2}+:\\d{1,2}+";
if (value.matches(regex)) {
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
} catch (Exception e) {
return null;
}
return date;
}
}
}
return null;
}
}
结果:
BasketBall{name='篮球', brand='乔丹', price=199.0, buyCount=5, produce=100, testTime=Sun Mar 08 23:56:03 CST 2020, ball=Ball{name='球', brand='null', createDate=null, createCompany=CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}}}
Ball{name='球', brand='null', createDate=null, createCompany=CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}}
CreateCompany{companyName='篮球公司', companyBrand='null', companyFoundDate=null}