通過反射級聯執行個體化對象
級聯執行個體化對象,是指對象包含其他對象執行個體的情況下執行個體化。要設定被包含對象的屬性就得對其實力化。
下面貼上代碼。
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());
}
}