Java反射

<h1>Java反射</h1>java

反射是Java的高級特性,讓本來是靜態類型的Java擁有了動態語言的特色。數組

Java反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲Java語言的反射機制。框架

就像鏡子同樣,反射回來的畫面和本來的物體同樣。jvm

反射是Java的重要特性,Java的Spring框架底層就基於反射。ide

Class類

Java中反射的實現是經過Class類表示的,只要獲取到Class的對象實例,就能夠拿到類的全部信息。函數

Class類表明字節碼,處於java.lang.reflect包下。測試

反射包下包含全部與反射有關的類,如java.lang.reflect.Fieldthis

每一個類都會在jvm中編譯成字節碼,jvm在加載類時對每一個對象都會生成一個Class對象,該對象可以在運行時得到類的全部信息,如構造方法、屬性、超類等。spa

一個類在 JVM 中只會有一個Class實例。code

獲取Class對象的三種方法

/**

 \* 獲取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對象。

一、經過對象的getClass()方法獲取Class對象,該方法是Object類下的方法

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屬性獲取Class對象
		Class c2=Man.class;
		System.out.println(c2);//class reflects.Man

三、經過Class類的靜態方法:forName(String className)(經常使用)

//經過Class類的靜態方法:forName(String  className)(經常使用)
		Class c3=Class.forName("reflects.Man");
		System.out.println(c3);//class reflects.Man

Class對象的實例只有一個,各類方式獲取的都是同一個對象。

經過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'}
相關文章
相關標籤/搜索