您的位置:首页 > 其它

通过反射自动级联实例化对象

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());

}
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
xiaolu_333 发布了30 篇原创文章 · 获赞 0 · 访问量 478 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐