知識點:java中的反射html
參考博客:https://www.cnblogs.com/tech-bird/p/3525336.htmljava
一:概述ide
Reflection(反射)是Java被視爲動態語言的關鍵,反射機制容許程序在執行期間藉助於Reflection ApI取得類的內部的信息,並能直接操做任意對象內部的屬性和方法this
Java反射機制主要提供的功能:spa
a.在運行時獲取任意一個類所具備成員變量、方法、構造器、父類、內部類等等代理
b.在運行時建立任意類的對象htm
c.在運行時,調用任意一個對象的屬性,方法等對象
d.生成動態代理(博客)blog
二:獲取Class實例的幾種方式get
Person.class類
public class Person extends Animals<String> implements Comparable{
public String name;
private int age;
int id;
public Person(){
System.out.println("無參構造器");
}
public Person(String name){
System.out.println("有參構造器:"+name);
}
public void showInfo(){
System.out.println("調用public修飾的方法");
}
public void showInfo1(String name){
System.out.println("展現對象的屬性方法——有參數:"+name);
}
public static void showInfo2(){
System.out.println("調用靜態方法");
}
private void showInfo3(){
System.out.println("調用private修飾的方法");
}
public void drink(){
System.out.println("喝水!");
}
@Override
public String toString() {
return "id"+this.id+"name:"+this.name+"age:"+age;
}
@Override
public int compareTo(Object o) {
return 0;
}
}
//獲取Class實例的幾種方式
public class TestReflection1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.運行時類的對象獲取,經過對象得到Class實例
Person p=new Person();
Class c1=p.getClass();
System.out.println(c1.getName());
//2.調用運行時類自己(.class屬性)
Class c2=Person.class;
System.out.println(c2.getName());
//3.經過Class的靜態方法className獲取
String className="com.kdgc.reflectiondemo.Person";//動態傳入className
Class c3= Class.forName(className);
System.out.println(c3.getName());
//4.經過類加載器
//ClassLoader classLoader=this.getClass().getClassLoader();
//Class c4= classLoader.loadClass(className);
}
}
三:獲取Class實例對應對象的屬性、方法、構造器
//獲取指定的屬性,方法,構造器
public class TestReflectionAppointProperty {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
//(1)獲取指定的屬性
Class c=Person.class;
//1.反射調用運行時類的指定屬性
//getField(String fileName):獲取運行時類中聲明爲public的指定屬性
Field name=c.getField("name");
//2.建立c對應運行時Person類的對象p
Person p=(Person) c.newInstance();
System.out.println(p);
//3.給運行時類的對象指定屬性賦值
name.set(p,"張三");
System.out.println(p);
// Field age=c.getField("age"); age的修飾符是private
//getDeclaredField():獲取運行時類中聲明的指定屬性
Field age=c.getDeclaredField("age");
//因爲訪問修飾符的限制,爲了保證給屬性成功賦值,須要操做前使得該屬性可被操做
age.setAccessible(true);
age.set(p,21);
System.out.println(p);
Field id=c.getDeclaredField("id");//id是默認的權限修飾符,這裏是能夠正常獲取的,若是報訪問權限異常,設置setAccessible(true)
// age.setAccessible(true);
id.set(p,1001);
System.out.println(p);
//(2)獲取指定的方法
//getMethod(String methodName,Class ...params):獲取運行時類中聲明爲public的方法
Method m=c.getMethod("showInfo");
// m.setAccessible(true); 不行
//調用指定的方法 invoke(Object obj,args)
m.invoke(p);
//調用有參數的成員方法
Method m1=c.getMethod("showInfo1",String.class);
m1.invoke(p,"實參名字");
//運行時類中得靜態方法的調用
Method m2=c.getMethod("showInfo2");
m2.invoke(Person.class);//直接傳入對應的類,調用相應的方法
//getDeclaredMethod(String fileName,...paras):調用運行時類中,聲明瞭的方法
Method m3=c.getDeclaredMethod("showInfo3");
m3.setAccessible(true);
m3.invoke(p);
//調用指定的構造器(有參),建立運行時類的對象
Constructor cons= c.getDeclaredConstructor(String.class);
cons.setAccessible(true);
cons.newInstance("構造器參數");
}}