通过反射自动级联实例化对象
2020-04-02 18:38
916 查看
通过反射级联实例化对象
级联实例化对象,是指对象包含其他对象实例的情况下实例化。要设置被包含对象的属性就得对其实力化。
下面贴上代码。
package reflection; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; interface IPerson { public void act(); } interface IMessage { public void send(); } class AMessage implements IMessage { public String aMessage; public AMessage() { } public String getAMessage() { return aMessage; } public void setAMessage(String aMessage) { this.aMessage = aMessage; } @Override public String toString() { return "AMessage{" + "aMessage='" + aMessage + '\'' + '}'; } @Override public void send() { System.out.println("这个是A消息"); } } class BMessage implements IMessage { public String bMessage; public BMessage() { } public String getBMessage() { return bMessage; } public void setBMessage(String bMessage) { this.bMessage = bMessage; } @Override public String toString() { return "BMessage{" + "bMessage='" + bMessage + '\'' + '}'; } @Override public void send() { System.out.println("这是B消息"); } } class Student implements IPerson { private String name; private int age; private AMessage aMessage; private BMessage bMessage; public Student(String name, int age) { this.name = name; this.age = age; } public Student() { } public void setName(String name) { this.name = name; } public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public AMessage getAMessage() { return aMessage; } public void setAMessage(AMessage aMessage) { this.aMessage = aMessage; } public BMessage getBMessage() { return bMessage; } public void setBMessage(BMessage bMessage) { this.bMessage = bMessage; } @Override public String toString() { return "姓名:" + name + "、年纪:" + age + "、a信息:" + aMessage + "、b信息:" + bMessage; } @Override public void act() { System.out.println("上课"); } } class Player implements IPerson { @Override public void act() { System.out.println("玩游戏"); } } class Factory { private Factory() {} /** * 反射与工厂模式的实现。实现多接口的反射实现 * * @param className 具体的全限定名 * @param clazz clazz用来确定泛型以及泛型返回值 * @param <T> 返回实体类 * @return */ public static <T> T Factor(String className, Class<T> clazz) { T t = null; try { t = (T) Class.forName(className).newInstance(); } catch (Exception e) { e.printStackTrace(); } return t; } /** * 用来对一个类的实现自动配置成员变量,并初始化 * * @param clazz * @param value * @param <T> * @return */ public static <T> T create(Class<T> clazz, String value) { //clazz用来确定泛型以及泛型返回值 try { Object object = clazz.getDeclaredConstructor().newInstance(); BeanUtils.setValue(object, value); return (T) object; } catch (Exception e) { e.printStackTrace(); } return null; } } class BeanUtils {//这个类实现类的反射 private BeanUtils() { } public static void setValue(Object obj, String value) { String[] results = value.split("\\|"); for (int i = 0; i < results.length; i++) { String[] attval = results[i].split(":"); try { //这个可以避免错误之后的停止,继续其他的属性反射设置 if (attval[0].contains(".")) {//表示需要级联更新 String[] temp = attval[0].split("\\.");//temp存放冒号前面的拆分。例如:bMessage.bMessage:我是b消息拆分出来就是:1 bMessage 2bMessage Object currentObject = obj; for (int j = 0; j < temp.length - 1; j++) { Method getMethod = currentObject.getClass().getDeclaredMethod("get" + StringUtils.toUppercase(temp[j])); Object tempObject = getMethod.invoke(currentObject); //获取到当前属性是否实例化 if (tempObject == null) { Field field = currentObject.getClass().getDeclaredField(temp[j]);//获取属性类型 Method method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.toUppercase(temp[j]), 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 method = currentObject.getClass().getDeclaredMethod("set" + StringUtils.toUppercase(temp[temp.length - 1]), field.getType()); method.invoke(currentObject, BeanUtils.convertAttributeValue(field.getType().getName(), attval[1])); } else { Field field = obj.getClass().getDeclaredField(attval[0]);//取得对应类型,通过类型去获得方法 Object val = BeanUtils.convertAttributeValue(field.getType().getName(), attval[1]); obj.getClass().getDeclaredMethod("set" + StringUtils.toUppercase(attval[0]), field.getType()).invoke(obj, val);//此句,获得class-》获取本类的方法-》钩子函数 } } catch (Exception e) { e.printStackTrace(); } } } /** * 实现属性类型转换 * * @param type 属性类型,通过Field获取 * @param value 属性类容,传入的都是字符串,需要将其变为指定类型 * @return 返回转换后的数据 */ private static Object convertAttributeValue(String type, String value) { if (null == type) { return null; } switch (type) { case "java.lang.String": return value; case "int": return Integer.parseInt(value); case "double": return Double.parseDouble(value); case "java.util.Date": 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(); } default: return null; } } } class StringUtils { private StringUtils() { } public static String toUppercase(String value) {//将首字母大写 if ("".equals(value) || null == value) { return value; } if (value.length() == 1) { return value.toUpperCase(); } else { return value.substring(0, 1).toUpperCase() + value.substring(1, value.length()); } } } public class ReflectionDemo { public static void main(String[] args) throws Exception { String value = "name:张三|age:100|aMessage.aMessage:我是a消息|bMessage.bMessage:我是b消息"; Student student = Factory.create(Student.class, value); System.out.println(student); System.out.println(student.getAMessage()); System.out.println(student.getBMessage()); } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 通过反射获取实例化对象的所有的属性值
- Java反射02 : Class对象获取的三种方式和通过反射实例化对象的两种方式
- Java 反射通过构造实例化对象
- java如何通过反射取得泛型的实例化对象
- 【怎样写代码】偷窥高手 -- 反射技术(七):通过反射实例化对象
- 通过反射途径获得的对象如何自动注入spring Bean
- C#通过反射实例化对象
- java通过暴力反射创建不可实例化类的对象实例
- java通过反射,只需要传了类名和参数,就可以根据不同参数的构造方法实例化对象
- 通过反射动态实例化对象中出现的一个奇怪问题
- 通过反射获取列表属性里保存的对象类型
- Java通过反射获取和设置对象的属性值
- JDBC通过反射机制批量的把List里面的对象添加到数据库中
- 02_3中方式的反射,通过Class.forName获得Class对象,通过类.class获得字节码对象,通过类实例.getClass()的方式获得Class对象
- struts2 表单对象没有自动实例化
- java反射,反射常用方法,获取类模板,通过类模板对象创建实体对象,类中未定义有参或无参构造器的情况下创建对象,不调用方法尝试给一个类的私有属性赋值,通过反射获取一个类的父类并获取它实现的接口
- DEVExpress XtraReport报表制作过程中绑定数据源的XRControl对象在值为0时不显示功能,通过代码自动实现
- protobuf在java应用中通过反射动态创建对象(DynamicMessage)
- 通过反射的方法,将源对象属性的值赋给目标对象的相同属性(举例)
- Java通过反射根据结果集ResultSet生成对应的JavaBean对象