- 反射機制概念
- 發射的使用場景
- 内省機制的使用
part1 :反射機制( jdk提供的一套api, 用于動态建立對象 )

java增強:反射機制,内省機制
part2: 反射的使用----兩個對象間屬性值的複制
(淺copy: 複制一個對象,會調用構造函數)
一個存在繼承關系的類: 對象的淺copy 代碼實作如下
1, 定義兩個javabean
public class Per {
//屬性
private int age;
private String name;
//構造
public Per(int age, String name) {
this.age = age;
this.name = name;
}
public Per() {
System.out.println("per 無參構造");
}
//get,set
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public class Student extends Per{
private int score;
public int getScore(){return score;}
public void setScore(int score){this.score=score;}
}
2, 建立對象1, 複制為對象2-----------反射:(構造+ 字段 ), ( 構造 + set/get ),(構造+ get)
//建立對象: 有屬性
Student st = new Student();
@before
public void init(){
st.setName("yyyy");
st.setAge(23);
st.setScore(99)
}
/**
* 反射: 通過屬性---copy對象
* @throws Exception
*/
@Test
public void t1() throws Exception {
//建立對象: 帶參構造
Class<?> clazz = Class.forName("Student");
Constructor<?> cons = clazz.getDeclaredConstructor(int.class);
Student student = (Student) cons.newInstance(80);
//擷取: 父類屬性--------------------------
Class<?> sup = clazz.getSuperclass();
Field age = sup.getDeclaredField("age");
age.setAccessible(true);
Field name = sup.getDeclaredField("name");
name.setAccessible(true);
//指派
age.set(student,st.getAge());
name.set(student,st.getName());
System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
}
/**
* 反射: 通過方法----copy對象
* @throws Exception
*/
@Test
public void t2() throws Exception {
//建立對象: 帶參構造
Class<?> clazz = Class.forName("Student");
Constructor<?> cons = clazz.getDeclaredConstructor(int.class);
Student student = (Student) cons.newInstance(89);
//擷取: 父類方法
Method setAge = clazz.getMethod("setAge", int.class);
Method setName = clazz.getMethod("setName", String.class);
//指派
setAge.invoke(student, st.getAge());
setName.invoke(student, st.getName());
System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
}
@Test
public void t3() throws Exception {
/**
* get--->set方法名, 參數
*/
//建立對象
Class<?> clazz = Class.forName("Student");
Student st2 = (Student) = clazz.newInstance();
//get方法---》set指派
Class clazz = st.getClass();
Method[] ms = clazz.getMethods();
//判斷: 是否getAge()
for (Method m : ms) {
String get = m.getName();
Class<?>[] paramType = m.getParameterTypes();
Class<?> retType = m.getReturnType();
if (get.startsWith("get") && paramType.length == 0 && retType != Class.class) {
Object returnVal = m.invoke(st);
String set = get.replace("get", "set");
//set : 參數---->第二個Obj指派
Method setMetho = clazz.getMethod(set, retType);
setMetho.invoke(st2, returnVal);
}
}
System.out.println(st2.getName() + "," + st2.getAge() );
}
part3: 内省機制---對象copy
@Test
public void t4() throws Exception {
Student st = new Student();
st.setAge(40);
st.setName("aaaa");
st.setScore(99);
Student st2 = new Student();
/**
* 内省: 實作---2個對象: 屬性拷貝
*/
BeanInfo binfo = Introspector.getBeanInfo(st.getClass());
PropertyDescriptor[] propDes = binfo.getPropertyDescriptors();
for (PropertyDescriptor proDescriptor : propDes) {
Method read = proDescriptor.getReadMethod();
Method write = proDescriptor.getWriteMethod();
String fieldName = proDescriptor.getName();
if (read != null && write != null) {
if (!fieldName.equals("class"))
write.invoke(st2, read.invoke(st));
}
}
System.out.println(st2.getName() + "," + st2.getAge()+ ","+st2.getScore());
}
part4: 對象的深度copy
( 不會調用構造方法, 父類和子類: 都要 implements Serializable)
@Test
public void t5() throws IOException, ClassNotFoundException {
Student st = new Student();
st.setAge(40);
st.setName("aaaa");
//把各個屬性: 組合為byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream objout = new ObjectOutputStream(baos);
objout.writeObject(st);
baos.close();
objout.close();
ObjectInputStream objin = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
Student student= (Student) objin.readObject();
objin.close();
System.out.println(student.getName() + "," + student.getAge()+","+student.getScore());
}