反射操作對象和屬性
eg:
class Person{
private Integer age;
public String name;
protected String addr;
Boolean is18;
}
class Student extends Person{
private Integer claaNum;
public String sex;
}
1.獲取Class對象
//獲取Class對象的三種方法
Class<?> clazz = Student.class;
Class<?> clazz = new Student().getClass();
Class<?> clazz = Class.forName("com.git.Student");
2.字段的操作
1.獲取字段的四種方法源碼(jdk1.8)
/**
* Returns an array containing {@code Field} objects reflecting all
* the accessible public fields of the class or interface represented by
* 返回對象的所有公開成員,包括該類和該類繼承的成員
*/
@CallerSensitive
public Field[] getFields() throws SecurityException {
//Member.PUBLIC,該類或該接口的所有公共成員的集合,包括繼承的成員
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);//這句代碼表名了只能返回自身和繼承類的共有屬性成員
return copyFields(privateGetPublicFields(null));
}
/**
*Returns an array of {@code Field} objects reflecting all the fields
* declared by the class or interface represented by this
* {@code Class} object. This includes public, protected, default
* (package) access, and private fields, but excludes inherited fields.
* 返回該類自身的所有成員集,包括public,protected,default,private 但是不包括繼承的
* /
@CallerSensitive
public Field[] getDeclaredFields() throws SecurityException {
//Member.DECLARED,該類或者該接口自己的成員集。不包括繼承的成員。
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyFields(privateGetDeclaredFields(false));
}
/**
* Returns a {@code Field} object that reflects the specified public member
* field of the class or interface represented by this {@code Class}
* object. The {@code name} parameter is a {@code String} specifying the
* simple name of the desired field.
* 返回該對象代表的類或者接口的公共成員的Field對象
* 參數 字段名
*/
@CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
/* * Returns a {@code Field} object that reflects the specified declared
* field of the class or interface represented by this {@code Class}
* object. The {@code name} parameter is a {@code String} that specifies
* the simple name of the desired field.
* 返回自定類或者接口的字段(Field)對象
* 參數 字段名,
*
* /
@CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
測試一:
public static void main(String[] args) {
Class<?> clazz = Student.class;
Field[] fields1 = clazz.getDeclaredFields();//本類的所有屬性
Field[] fields2 = clazz.getFields();//本類或者父類的共有屬性
Arrays.stream(fields1).forEach(System.out::println);
System.out.println("========================分割線========================");
Arrays.stream(fields2).forEach(System.out::println);
}
//結果
private java.lang.Integer com.qdz.qdzmart.framework.utils.Student.claaNum
public java.lang.String com.qdz.qdzmart.framework.utils.Student.sex
========================分割線========================
public java.lang.String com.qdz.qdzmart.framework.utils.Student.sex
public java.lang.String com.qdz.qdzmart.framework.utils.Person.name
測試二:
Field field1 = clazz.getField("name");//可以獲取
Field field7 = clazz.getField("sex");//可以獲取
Field field3 = clazz.getField("claaNum");//報錯
Field field4 = clazz.getField("age");//報錯
Field field5 = clazz.getField("addr");//報錯
Field field6 = clazz.getField("is18");//報錯
測試三:
Field field7 = clazz.getDeclaredField("sex");//可以獲取
Field field3 = clazz.getDeclaredField("claaNum");//可以獲取
Field field1 = clazz.getDeclaredField("name");//報錯
Field field4 = clazz.getDeclaredField("age");//報錯
Field field5 = clazz.getDeclaredField("addr");//報錯
Field field6 = clazz.getDeclaredField("is18");//報錯
以上四種方法用於數組等時需要注意下。
2.給成員賦值
這裏有點坑