<h1>Java反射</h1>java
反射是Java的高級特性,讓本來是靜態類型的Java擁有了動態語言的特色。數組
Java反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲Java語言的反射機制。框架
就像鏡子同樣,反射回來的畫面和本來的物體同樣。jvm
反射是Java的重要特性,Java的Spring框架底層就基於反射。ide
Java中反射的實現是經過Class類表示的,只要獲取到Class的對象實例,就能夠拿到類的全部信息。函數
Class類表明字節碼,處於java.lang.reflect
包下。測試
反射包下包含全部與反射有關的類,如java.lang.reflect.Field
this
每一個類都會在jvm中編譯成字節碼,jvm在加載類時對每一個對象都會生成一個Class對象,該對象可以在運行時得到類的全部信息,如構造方法、屬性、超類等。spa
一個類在 JVM 中只會有一個Class實例。code
/** \* 獲取Class對象的三種方式 \* 1 Object ——> getClass(); \* 2 任何數據類型(包括基本數據類型)都有一個「靜態」的class屬性 \* 3 經過Class類的靜態方法:forName(String className)(經常使用) */
創建包reflects
,在包下建立父類Person,子類Man.
class Person{ String name; public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "{" + " name='" + getName() + "'" + "}"; } } class Man extends Person{ private int age; public Man(String name,int age) { super(name); this.age=age; } @Override public String toString() { return "Man [age=" + age + ", name=" + name + "]"; } }
在主方法中測試Class對象。
public static void main(String[] args) throws Exception { //經過對象的getClass()方法獲取Class對象,該方法是Object類下的方法 Man man=new Man("張三",8); Class c1=man.getClass(); //打印Class對象 System.out.println(c1);//class reflects.Man System.out.println(c1.getName());//reflects.Man System.out.println(c1.getSimpleName());//Man System.out.println(c1.getTypeName());//reflects.Man //獲取public構造函數數組 System.out.println(c1.getConstructors()[0]);//public reflects.Man(java.lang.String,int) //獲取超類 System.out.println(c1.getSuperclass());//class reflects.Person //獲取private字段數組 Field[] f=c1.getDeclaredFields(); for(Field f0:f) { System.out.println(f0);//private int reflects.Man.age } }
//經過「靜態」的class屬性獲取Class對象 Class c2=Man.class; System.out.println(c2);//class reflects.Man
//經過Class類的靜態方法:forName(String className)(經常使用) Class c3=Class.forName("reflects.Man"); System.out.println(c3);//class reflects.Man
經過hashCode()方法測試。
System.out.println(c1.hashCode());//31168322 System.out.println(c2.hashCode());//31168322 System.out.println(c3.hashCode());//31168322 //經過hashCode能夠看出三種方法生成的對象時同一個 System.out.println(c1==c2);//true System.out.println(c1.equals(c3));//true
測試經過反射建立對象,而且修改方法。
Constructor con= c1.getConstructor(String.class,int.class);//獲取構造器對象 Man man2=(Man)con.newInstance("jim",10);//經過構造器對象建立實例 System.out.println(man2); //Man [age=10, name=jim] Class c4=c1.getSuperclass();//獲取超類 Constructor p=c4.getConstructor(String.class); Person person=(Person)p.newInstance("hon"); System.out.println(person); Method method= c4.getDeclaredMethod("setName", String.class);//獲取方法對象 method.invoke(person, "Tony");//激活方法修改器 System.out.println(person); //{ name='hon'} //{ name='Tony'}