1、传统开发过程中,简单Java类中如果有大量的属性,那么就会存在大量的setter与getter方法,从而导致代码编写的重复性会非常高。要想解决对象的重复处理操作就可以利用反射机制。
2、属性自动设置解决方案
import java.lang.reflect.* ;
public class BDemo {
public static void main(String[] args) throws Exception {
String value = "ename:Bob|job:Boss" ;
Emp emp = ClassInstanceFactory.creat(Emp.class, value) ;
System.out.println("姓名:" + emp.getEname() + ";职位:" + emp.getJob()) ;
}
}
class ClassInstanceFactory {
private ClassInstanceFactory() {}
/**
*实例化对象的创建方法
*@param clazz 要进行反射实例化的Class类对象,即有Class就可以反射实例化对象
*@param value 要设置给对象属性的属性值
*@return 一个已经配置好属性内容的Java类对象
*/
public static <T> T creat(Class<T> clazz, String value) {
//使用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造
try{
Object obj = clazz.getDeclaredConstructor().newInstance() ;
BeanUtils.setValue(obj,value) ; //通过反射设置属性
return (T)obj ;
}catch(Exception e) {
e.printStackTrace() ;
return null ;
}//如果此处不进行异常处理,那么在属性设置错误时程序会停止执行,进行处理后如果属性设置错误就返回null,不影响其他部分执行
}
}
//实现首字母大写
class StringUtils {
public static String initcap(String str) {
if(str == null || "".equals(str)) {
return str ;
}
if(str.length() == 1) {
return str.toUpperCase() ;
}else {
return str.substring(0,1).toUpperCase() + str.substring(1) ;
}
}
}
//进行Bean处理的类
class BeanUtils {
private BeanUtils() {}
/**
*实现指定对象的属性设置
*@param obj 要进行反射操作的实例化对象
*@param value 包含指定内容的字符串,格式:例:ename:Bob|job:Boss
*@return 一个已经配置好属性内容的Java类对象
*/
public static void setValue(Object obj, String value) {
String results [] = value.split("\\|") ;
for(int x = 0 ; x < results.length ; x ++) {
String attribute [] = results[x].split(":") ;
try {
Field field = obj.getClass().getDeclaredField(attribute[0]) ; //获取成员
Method setMethod = obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attribute[0]),field.getType()) ;
setMethod.invoke(obj,attribute[1]) ; //调用setter方法设置内容
}catch(Exception e) {
e.printStackTrace() ;
}
}
}
}
class Emp {
private String ename ;
private String job ;
public void setEname(String ename) {
this.ename = ename ;
}
public String getEname() {
return this.ename ;
}
public void setJob(String job) {
this.job = job ;
}
public String getJob() {
return this.job ;
}
}
【重要】3、级联对象实例化与级联属性赋值
import java.lang.reflect.* ;
import java.text.ParseException ;
import java.text.SimpleDateFormat ;
import java.util.Date ;
public class BDemo {
public static void main(String[] args) throws Exception {
String value = "empo:1314|ename:Bob|job:Boss|date:1998-03-04|" + "dept.dname:技术部|dept.company.name:www";
Emp emp = ClassInstanceFactory.creat(Emp.class, value) ;
System.out.println("编号:" + emp.getEmpo() + ";姓名:" + emp.getEname() + ";职位:" + emp.getJob() + ";入职日期:" + emp.getDate() + ";公司:" + emp.getDept().getCompany().getName() + ";部门:" + emp.getDept().getDname() ) ;
}
}
class ClassInstanceFactory {
private ClassInstanceFactory() {}
/**
*实例化对象的创建方法
*@param clazz 要进行反射实例化的Class类对象,即有Class就可以反射实例化对象
*@param value 要设置给对象属性的属性值
*@return 一个已经配置好属性内容的Java类对象
*/
public static <T> T creat(Class<T> clazz, String value) {
//使用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造
try{
Object obj = clazz.getDeclaredConstructor().newInstance() ;
BeanUtils.setValue(obj,value) ; //通过反射设置属性
return (T)obj ;
}catch(Exception e) {
e.printStackTrace() ;
return null ;
}//如果此处不进行异常处理,那么在属性设置错误时程序会停止执行,进行处理后如果属性设置错误就返回null,不影响其他部分执行
}
}
//实现首字母大写
class StringUtils {
public static String initcap(String str) {
if(str == null || "".equals(str)) {
return str ;
}
if(str.length() == 1) {
return str.toUpperCase() ;
}else {
return str.substring(0,1).toUpperCase() + str.substring(1) ;
}
}
}
//进行Bean处理的类
class BeanUtils {
private BeanUtils() {}
/**
*实现指定对象的属性设置
*@param obj 要进行反射操作的实例化对象
*@param value 包含指定内容的字符串,格式:例:ename:Bob|job:Boss
*@return 一个已经配置好属性内容的Java类对象
*/
public static void setValue(Object obj, String value) {
String results [] = value.split("\\|") ;
for(int x = 0 ; x < results.length ; x ++) {
String attribute [] = results[x].split(":") ;
try {
if(attribute[0].contains(".")) { //多级配置
String temp [] = attribute[0].split("\\.") ;
//进行实例化,最后一位是指定类中的属性名不用实例化
Object currentObject = obj ;
for(int y = 0 ; y < temp.length - 1 ; y ++) {
Method getMethod = currentObject.getClass().getDeclaredMethod("get" + StringUtils.initcap(temp[y])) ;
Object tempObject = getMethod.invoke(currentObject) ; //转型
if(tempObject == null) { //对象未被实例化
Field field = currentObject.getClass().getDeclaredField(temp[y]) ;
Method method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[y]),field.getType()) ;
Object newObject = field.getType().getDeclaredConstructor().newInstance() ;
method.invoke(currentObject,newObject) ;
currentObject = newObject ;
}else {
currentObject = tempObject ;
}
}
//进行属性内容的设置
Field field = currentObject.getClass().getDeclaredField(temp[temp.length - 1]);
Method setMethod = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[temp.length - 1]),field.getType()) ;
Object val = BeanUtils.convertAttributeValue(field.getType().getName(),attribute[1]) ;
setMethod.invoke(currentObject,val) ;
} else {
Field field = obj.getClass().getDeclaredField(attribute[0]) ; //获取成员
Method setMethod = obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attribute[0]),field.getType()) ;
Object val = BeanUtils.convertAttributeValue(field.getType().getName(),attribute[1]) ;
setMethod.invoke(obj,val) ; //调用setter方法设置内容
}
}catch(Exception e) {
e.printStackTrace() ;
}
}
}
/**
*实现属性类型转换
*@param Type 属性类型,通过Field获取的
*@param value 属性的内容,传入的都是字符串,需要将其变为指定类型
*@return 转婚后的数据
*/
//因为invoke()方法中参数value是Object类型
public static Object convertAttributeValue(String type,String value) {
if("long".equals(type) || "java.lang.long".equals(type)) {
return Long.parseLong(value) ;
}else if("int".equals(type) || "java.lang.int".equals(type)) {
return Integer.parseInt(value) ;
}else if("double".equals(type) || "java.lang.double".equals(type)) {
return Double.parseDouble(value) ;
}else if("java.util.Date".equals(type)) {
SimpleDateFormat sdf = null ;
if(value.matches("\\d{4}-\\d{2}-\\d{2}")) {
sdf = new SimpleDateFormat("yyyy-MM-dd") ;
} else if(value.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;
} else {
return new Date() ;
}
try {
return sdf.parse(value) ;
} catch (ParseException e) {
e.printStackTrace() ;
return new Date() ;
}
}else {
return value ;
}
}
}
//公司类
class Company {
private String name ;
private Date createdate ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatedate() {
return createdate;
}
public void setCreatedate(Date createdate) {
this.createdate = createdate;
}
}
//部门类
class Dept {
private String dname ;
private String loc ;
private Company company ;
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
}
//职员类
class Emp {
private String ename ;
private String job ;
private long empo ;
private Date date ;
private Dept dept ;
public void setEname(String ename) {
this.ename = ename ;
}
public String getEname() {
return this.ename ;
}
public void setJob(String job) {
this.job = job ;
}
public String getJob() {
return this.job ;
}
public void setEmpo(long empo) {
this.empo = empo ;
}
public long getEmpo() {
return this.empo ;
}
public void setDate(Date date) {
this.date = date ;
}
public Date getDate() {
return this.date ;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
}
运行结果: