java反射 reflex 反射獲取方法 反射獲取屬性
一、反射概念:
1、一定是在運行狀態中進行的
2、對於任意一個實體類,都能夠知道這個類的所有屬性和方法
3、對於任意一個對象,都能夠調用它的任意方法和屬性
這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制
二、利用反射我們能做什麼
1、在運行時判斷任意一個對象所屬的類
2、在運行時構造任意一個類的對象
3、在運行時判斷任意一個類所具有的成員變量和方法
4、在運行時調用任意一個對象的方法
5、生成動態代理
三、獲取class對象
三種方法
1、Class.forname(全類名) (帶異常處理 推薦使用)
//獲取該對象的class
Class c3 = null;
try {
c3 = Class.forName("com.test.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//打印獲取的類名稱
System.out.println("類名稱:"+c3.getName());
2、類名.Class
/獲取該對象的class
Class c2 = Person.class;
//打印獲取的類名稱
System.out.println("類名稱:"+c2.getName());
3、對象.getclass()
//獲取該對象的class
Class c1 = person.getClass();
//打印獲取的類名稱
System.out.println("類名稱:"+c1.getName());
注意凡是反射必須是Class
四、反射獲取方法
1、第一步獲取反射接口
//1、先獲取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、獲取方法
分2種
①獲取所有的公共方法 本類以及父類中以及接口中所有的公共方法,符合訪問修飾符規律 public的方法 private不行
②獲取當前類的所有方法(1.忽略訪問修飾符規律 2.只限當前類,不含父類)
//2、獲取方法
// 1)獲取所有的公共方法 本類以及父類中以及接口中所有的方法,2.符合訪問修飾符規律 public的方法 private不行
Method[] methods = stuClass.getMethods();
for (Method method : methods) {
System.out.println("獲取所有的方法:" + method);
}
// 2)獲取當前類的所有方法(1.忽略訪問修飾符規律 2.只限當前類)
Method[] methods1 = stuClass.getDeclaredMethods();
for (Method method : methods1) {
System.out.println("獲取當前類的方法:" + method);
}
五、反射獲取屬性
分2種
1、首先,依舊要獲取class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2、反射獲取屬性
也分2種
①所有的公共屬性 本類及其父類中的
②本類中的屬性
//2、獲取屬性
// 1)所有的公共屬性 本類及其父類中的
Field[] fields = stuClass.getFields();
for (Field field : fields) {
System.out.println("所有的公共public屬性:" + field);
}
// 2)本類中的屬性
Field[] fields1 = stuClass.getDeclaredFields();
for (Field field : fields1) {
System.out.println("本類中的屬性:" + field);
}
六、反射操作屬性
方法一:
1、首先獲取Class對象
2、在獲取Object對象
3、在Object對象轉爲實例
4、設置實例的屬性
上代碼
//1、先獲取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//方法一
// 1)獲取對象
Object instance = null;
try {
instance = stuClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//2)、轉化爲實例
Student stud = (Student)instance;
//3)、設置實例的屬性
stud.setStuNum("10001");
stud.setName("張三");
System.out.println("1、重新設置的屬性 姓名:"+stud.getName()+" 學號:"+stud.getStuNum());
方法二:
1、首先獲取Class對象
2、反射獲取屬性
3、反射方法設置屬性值
//1、先獲取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Field stuNumField = null;
Field stuClassNameField = null;
Field stuGradeField = null;
try {
//2、反射獲取屬性
stuNumField = stuClass.getDeclaredField("stuNum"); // private 屬性
stuClassNameField = stuClass.getDeclaredField("className"); // private 屬性
stuGradeField = stuClass.getDeclaredField("grade"); // public 屬性
//操作私有屬性 一定要 設置 爲true public屬性則不需 否則報錯
stuNumField.setAccessible(true);
stuClassNameField.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
try {
//3、給屬性賦值
stuNumField.set(stud,"10002"); //相當於stud.setStuNum("10002");
stuClassNameField.set(stud,"計算機班");
stuGradeField.set(stud,"一年級");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("2、重新設置的屬性 班級:"+stud.getClassName()+" 學號:"+stud.getStuNum()+" 年級:"+stud.getGrade());
注意:操作私有屬性 setAccessible 方法一定要 設置 爲true, public屬性則不需 否則報錯
七、反射操作實例的方法
步驟:
1、先獲取反射的Class
2、獲取需要操作的方法
3、setAccessible 設置爲可利用 不然會報錯,public方法則不需
4、獲取實例對象
5、調用該方法
奉上代碼:
//1、先獲取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method method = null;
try {
//2、獲取方法
method = stuClass.getDeclaredMethod("setStuNum",String.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
//3、設置爲可利用 不然會報錯
method.setAccessible(true);
Student person = null;//將instance轉化爲Person
try {
//4、獲取實例對象
person = (Student)stuClass.newInstance();
//5、調用該方法
method.invoke(person,"10003");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}catch (InvocationTargetException e) {
e.printStackTrace();
}
八、反射操作構造方法(構造方法分public和 private)
步驟:
1、先獲取反射的Class
2、獲取需要構造方法(分無參數和有參數 2種)
3、調用構造方法(無參數和有參數 2種)
上代碼:
//1、先獲取反射的Class
Class<?> stuClass = null;
try {
stuClass = Class.forName("com.test.Student");
System.out.println(stuClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//獲取全部公共構造方法 public
Constructor<?>[] constructors = stuClass.getConstructors();
for (Constructor constructor:constructors) {
System.out.println("全部公共構造方法"+constructor);
}
//2、獲取本類的公共構造方法
Constructor<?>[] constructors02 = stuClass.getDeclaredConstructors();
for (Constructor constructor:constructors02) {
System.out.println("本類構造方法" + constructor);
}
try {
//3-1獲取指定 無參數的構造方法
Constructor<?> constructor02 = stuClass.getConstructor();
Student stud = null;
try {
//如果構造函數是private 一定要加入下面這句話 否則報錯
//constructor02.setAccessible(true);
stud = (Student) constructor02.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("本類無參數構造方法的對象:"+stud);
//3-2獲取指定 有參數的構造方法
Constructor<?> constructor03 = stuClass.getConstructor(String.class);
Student stud2 = null;//轉化爲Person類
try {
//如果構造函數是private 一定要加入下面這句話 否則報錯
//constructor02.setAccessible(true);
constructor03.setAccessible(true);
//4 調用構造方法 傳參
stud2 = (Student)constructor03.newInstance("10004");
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
System.out.println("本類指定的有參數的構造方法的對象:"+stud2);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
九、使用反射給對象賦值通用方法
//動態給對象賦值
public void setProperty(Object obj, String propertyName, Object value) throws
NoSuchFieldException, IllegalAccessException {
Class<?> perclass = obj.getClass();
Field field = perclass.getDeclaredField( propertyName);//獲得屬性
field.setAccessible(true);//因爲是私有的
field.set(obj,value);//(對象,方法)
}
調用
//使用反射給對象賦值通用方法
Student student = new Student();
try {
test.setProperty(student,"stuNum","10007");
System.out.println("動態設置的屬性爲:stuNum="+student.getStuNum());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}