这篇文章主要讲解了“什么是级联对象实例化”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是级联对象实例化”吧!
如果现在给定的类对象中存在有其它的引用的级联关系的情况下,称为多级设置。例如:一个雇员属于一个部门,一个部分属于一个公司,所以这时对于简单Java类的基本关系定义如下:
Company:
class Company{private String name;private Date createdate;
}
Dept:
class Dept{private String dname;private String loc;private Company company;
}
Emp:
class Emp{private Long empno;private String ename;private String job;private double salary;private Date hireDate;private Dept dept;
}
如果要通过Emp进行操作,则应该使用“.”作为级联关系的处理:
dept.dname:财务部 | Emp类实例化对象.getDept().setDname("财务部") |
---|---|
dept.company.name:MLDN | Emp类实例化对象.getDept()..getCompany().setName("MLDN") |
考虑到代码的简洁性,所以应该考虑可以通过级联的配置自动实现类中属性的实例化。
String value="empno:7369|ename:Smith|job:Clerk|salary:750.00|hiredate:1989-10-10" + "dept.dname:财务部|dept.company.name:MLDN";
现在的属性存在有多级的关系,那么对于多级的关系就必须与单级的配置区分开
import java.lang.reflect.Field;import java.lang.reflect.Method;public class JavaAPIDemo {public static void main(String[] args)throws Exception{
String value="empno:7369|ename:Smith|job:Clerk|salary:750.00|hiredate:1989-10-10" + "dept.dname:财务部|dept.company.name:MLDN";
Emp emp = ClassInstanceFactory.create(Emp.class, value);
System.out.println("雇员编号:" + emp.getEmpno() + "、姓名:" + emp.getEname() + "、职位:" + emp.getJob() + "、基本工资:" + emp.getSalary() + "、受雇日期:" + emp.getHiredate());
System.out.println(emp.getDept());
System.out.println(emp.getDept().getCompany());
}
}class ClassInstanceFactory{private ClassInstanceFactory(){}/**
* 实例化对象的创建方法,该对象可以根据传入的字符串结构:"属性:内容|属性:内容"
* @param clazz 要进行反射实例化的Class对象,有Class就可以反射实例化对象
* @param value 要设置给对象的属性内容
* @return 一个已经配置好属性内容的Java对象
*/public static <T> T create(Class<?> clazz,String value){// 如果要想采用反射进行简单Java类对象属性设置的时候,类中必须要有无参构造try {
Object obj = clazz.getDeclaredConstructor().newInstance();
BeanUtils.setValue(); //通过反射设置属性return (T) obj; //返回对象}catch (Exception e) {
e.printStackTrace(); //如果此时真的出现了错误,本质上抛出异常也没用return 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);
}
}
}class BeanUtils{ //进行Bean处理的类private BeanUtils(){}/**
* 实现指定对象的属性设置
* @param obj 要进行反射操作的实例化对象
* @param value 包含有指定内容的字符串,格式"属性:内容|属性:内容"
*/public static void setValue(Object obj,String value){
String results [] = value.split("\\|");//按照"|"进行每一组属性的拆分for (int x = 0; x < results.length; x ++) { //循环设置属性内容//attval [0]保存的是属性名称,attval [1]保存的是属性内容String attval [] = results[x].split(":"); //获取“属性名称”和内容try {if (attval[0].contains(".")) { //多级配置String temp [] = attval[0].split("\\.");
Object currentObject = obj;// 最后一位肯定是指定类中的属性名称,所以不在本次实例化处理的范畴之内for (int y = 0 ; y < temp.length - 1 ; y ++) { // 实例化// 调用了相应的getter方法,如果getter方法返回了null,表示该对象未实例化Method getMethod = obj.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;
}
System.out.println(temp[y] + "--" + currentObject);
}
}else {
Field field = obj.getClass().getDeclaredField(attval[0]); //获取成员Method setMethod = obj.getClass().getDeclaredMethod("set" + StringUtils.initcap(attval [0]), field.getType());
Object convertValue = BeanUtils.convertAttributeValue(field.getType().getName(), attval[1]);
setMethod.invoke(obj, convertValue); //调用setter方法设置内容}
}catch (Exception e) {}
}
}/**
* 实现属性类型转换处理
* @param type 属性类型,通过Field获取
* @param value 属性的内容,传入的都是字符串,需要将其变为指定类型
* @return 转换后的数据类型
*/private 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 Integer.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) {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 long empno;private String ename;private String job;private double salary;private Date hiredate;private Dept dept;public Dept getDept() {return dept;
}public void setDept(Dept dept) {this.dept = dept;
}public void setEname(String ename) {this.ename = ename;
}public void setJob(String job) {this.job = job;
}public String getEname() {return ename;
}public String getJob() {return job;
}public long getEmpno() {return empno;
}public void setEmpno(Long empno) {this.empno = empno;
}public double getSalary() {return salary;
}public void setSalary(double salary) {this.salary = salary;
}public Date getHiredate() {return hiredate;
}public void setHiredate(Date hiredate) {this.hiredate = hiredate;
}
}
这些自动的级联配置的实例化处理操作,在以后进行项目的编写之中一定会使用到。
现在已经成功的实现级联的对象实例化处理,那么随后就需要去考虑级联的属性的设置了,在之前考虑级联对象实例化处理时,循环时都是少了一位的。
for (int y = 0 ; y < temp.length - 1 ; y ++) { // 实例化// 调用了相应的getter方法,如果getter方法返回了null,表示该对象未实例化Method getMethod = obj.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;
}
}
当此时代码循环处理完成之后,currentObject表示的就是可以进行setter方法调用的对象了,并且理论上该对象一定不可能为null,随后就可以按照我们之前的方式利用对象进行setter方法调用。
范例:实现对象的级联属性设置
//进行属性内容的设置Field field = currentObject.getClass().getDeclaredField(temp[temp.length - 1]); //获取成员Method setMethod = currentObject.getClass().getDeclaredMethod("set" + StringUtils.initcap(temp[temp.length - 1]), field.getType());
Object convertValue = BeanUtils.convertAttributeValue(field.getType().getName(), attval[1]);
setMethod.invoke(currentObject, convertValue); //调用setter方法设置内容
感谢各位的阅读,以上就是“什么是级联对象实例化”的内容了,经过本文的学习后,相信大家对什么是级联对象实例化这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/1240933/blog/5021113