1.定義: 在運行狀態中對於任意一個類都能夠知道這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。 2.應用場景: 編碼階段不知道需要實例化的類名是哪個,需要在runtime從配置文件中載入 在runtime ...
1.定義:
- 在運行狀態中對於任意一個類都能夠知道這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
2.應用場景:
- 編碼階段不知道需要實例化的類名是哪個,需要在runtime從配置文件中載入
- 在runtime階段,需要臨時訪問類的某個私有屬性
3.定義People和子類Men
-
public class People { private int age; private String name; public int hight; public People() { } public People(int age, String name) { this.age = age; this.name = name; } public People(String name) { this.name = name; } public void eat(String food) { System.out.println("人吃飯"); } private String sleep() { System.out.println("人睡覺"); return "2"; } public String grow() { return "成長"; } }
public class Men extends People { public int age; private String name; private Men(){} public Men(int age,String name){ this.age=age; this.name=name; } public void eat(String food){ System.out.println("男人吃飯"); } private String sleep(){ System.out.println("男人睡覺"); return "2"; } }
4.獲取類對象的三種方式
Class clazz = Men.class;//根據類名獲得class Class clazz1 = Class.forName("reflect.Men");//根據類路徑獲得class Men men = new Men(12, "男"); Class clazz2 = men.getClass();//通過對象獲得 System.out.println(clazz == clazz1);//相等 System.out.println(clazz == clazz2);//相等
5.獲得構造函數
//獲取構造器 Constructor[] constructors = clazz.getConstructors();//獲取全部構造器(公有)(包括父類) Constructor[] constructors1 = clazz.getDeclaredConstructors();//獲取全部構造器(無論類型)(不包括父類) Constructor constructor = clazz.getConstructor(int.class, String.class);//獲取給定參數的構造器(公有)(包括父類) Constructor constructor1 = clazz.getDeclaredConstructor(int.class, String.class);//獲取給定參數的(無論類型)(不包括父類) System.out.println("參數類型為(int,String)的公有構造器:\n" + constructor); System.out.println("參數類型為(int,String)的構造器(無論類型):\n" + constructor1); System.out.println("全部公有構造器:"); for (Constructor c : constructors ) { System.out.println(c); } System.out.println("全部構造器(無論類型):"); for (Constructor c : constructors1 ) { System.out.println(c); } //用構造器創建對象 Men o = (Men) constructor.newInstance(1, "男"); System.out.println("構造器創建的對象:\n" + o);
- 執行結果
參數類型為(int,String)的公有構造器:
public reflect.Men(int,java.lang.String)
參數類型為(int,String)的構造器(無論類型):
public reflect.Men(int,java.lang.String)
全部公有構造器:
public reflect.Men(int,java.lang.String)
全部構造器(無論類型):
private reflect.Men()
public reflect.Men(int,java.lang.String)
構造器創建的對象:
reflect.Men@27c170f0
6.獲得對象的參數
System.out.println("參數名為age的公有欄位:\n" + clazz.getField("age"));//得到公有欄位(包括父類) System.out.println("參數名為age的欄位(無論類型):\n" + clazz.getDeclaredField("age"));//得到所有類型欄位(不包括父類) Field[] fields = clazz.getFields(); System.out.println("所有公有的欄位"); for (Field f : fields ) { System.out.println(f);//得到所有公有的欄位(包括父類) } Field[] fields1 = clazz.getDeclaredFields(); System.out.println("所有欄位(無論類型)"); for (Field f : fields1 ) { System.out.println(f);//得到所有欄位無論類型(不包括父類) } Field f1 = clazz.getField("age"); f1.set(men, 12);//給對象屬性賦值
- 執行結果
參數名為age的公有欄位:
public int reflect.Men.age
參數名為age的欄位(無論類型):
public int reflect.Men.age
所有公有的欄位
public int reflect.Men.age
public int reflect.People.hight
所有欄位(無論類型)
public int reflect.Men.age
private java.lang.String reflect.Men.name
7.獲得方法
Method method = clazz.getMethod("eat",String.class);//獲取方法名為eat參數類型為String的公有方法(包括父類) Method method1 = clazz.getDeclaredMethod("eat",String.class);//獲取方法名為eat參數類型為String的方法(無論類型)(不包括父類) Method[] methods = clazz.getMethods();//獲取全部公有方法(包括父類) Method[] methods1 = clazz1.getDeclaredMethods();//獲取全部方法(無論類型)(不包括父類) System.out.println("方法名為eat,參數類型為String的公有方法:\n"+method); System.out.println("方法名為eat,參數類型為String的方法(無論類型):\n"+method); System.out.println("全部公有方法:"); for (Method m:methods ) { System.out.println(m); } System.out.println("全部方法(無論類型):"); for (Method m1:methods1 ) { System.out.println(m1); } //調用方法 method.invoke(men,"蘋果");
- 執行結果
方法名為eat,參數類型為String的公有方法:
public void reflect.Men.eat(java.lang.String)
方法名為eat,參數類型為String的方法(無論類型):
public void reflect.Men.eat(java.lang.String)
全部公有方法:
public void reflect.Men.eat(java.lang.String)
public java.lang.String reflect.People.grow()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
全部方法(無論類型):
private java.lang.String reflect.Men.sleep()
public void reflect.Men.eat(java.lang.String)
男人吃飯
***********註意點***************
帶有Declared內容的方法是獲取不包含父類的所有訪問限制內容,不帶Declared的是獲取包含父類的public的內容