阿猛學習筆記java十二

qq_40298829 發表於 2020-10-28

十八反射

例項化物件:類–>物件

通過:物件–>類名

1.作用

通過反射可使程式程式碼訪問裝載到JVM的類的內部資訊

​ 獲得已裝載類的屬性資訊

​ 獲得已裝載類的方法

​ 獲得已裝載類的構造方法資訊

2.反射常用類

都位於java.lang.reflect包

Class

代表一個類

​ 反射機制的起源和入口

​ 提供了獲取類資訊的相關方法

​ 用於獲取與類相關的各種資訊

常用方法

​ getPackage() 獲得類的所屬包

​ getSuperClass() 獲得類的父類對應的Class物件

​ getName() 獲得類的完整名字

​ getDeclaredConstructors() 獲得類所有構造方法

​ getConstrutors() 獲得類public型別的構造方法

​ getConstrutor(Class[] args) 獲得類特定構造方法

​ getDeclaredFields() 獲得類所有屬性

​ getFields() 獲得類public型別屬性

​ getField(String name) 獲得類指定屬性

​ getDeclaredMethods() 獲得類的所有方法

​ getMethods() 獲得類public型別的方法

​ getMethod(String name,Class[] args) 獲得類指定方法

Constructor

代表類的構造方法

Field

代表類的成員屬性

Method

代表類的成員方法

Array

代表動態陣列的建立以及訪問陣列元素的靜態方法

public class S1Reflect {
	public	int id=1;
	String name="李四";
	private int age=14;
	public S1Reflect(){	
	}	
	public S1Reflect(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public void function(){	
	}
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
		//1.例項化物件
		S1Reflect reflect=new S1Reflect();
		//通過物件得到對應的反射類
		Class<?> c=reflect.getClass();
		//通過反射類得到該類物件
		S1Reflect reflect2=(S1Reflect) c.newInstance();
		System.out.println(reflect2.name);
		System.out.println("所屬包:"+c.getPackage());
		System.out.println("得到父類:"+c.getSuperclass());
		System.out.println("類名:"+c.getName());
		Constructor<?>[] constructors=c.getDeclaredConstructors();
		System.out.print("通過反射類得到所有構造方法:");
		for(Constructor constructor:constructors){
			System.out.print(constructor.getName()+"\t");
		}
		System.out.println();	
		System.out.print("通過反射類得到所有屬性:");
		Field[] fields=c.getDeclaredFields();
		for(Field field:fields){
			System.out.print(field.getName()+"\t");
		}
		System.out.println();
		System.out.print("通過反射類得到public型別屬性:");
		Field[] fieldsP=c.getFields();
		for(Field field:fieldsP){
			System.out.print(field.getName()+"\t");
		}
		System.out.println();
		System.out.print("通過反射類得到所有方法:");
		Method methods[]=c.getDeclaredMethods();
		for(Method method: methods){
			System.out.print(method.getName()+"\t");
		}
		System.out.println();
	}
}

李四
所屬包:package S1022Reflect
得到父類:class java.lang.Object
類名:S1022Reflect.S1Reflect
通過反射類得到所有構造方法:S1022Reflect.S1Reflect	S1022Reflect.S1Reflect	
通過反射類得到所有屬性:id	name	age	
通過反射類得到public型別屬性:id	
通過反射類得到所有方法:main	function	

3.生成Class(反射類)的方法

1.物件名.getClass()

3.類名.class

2.Class.forName()

4.包裝類.TYPE

public class S2GetReflectClass {

	public static void main(String[] args) throws ClassNotFoundException {
		//1.通過物件名.getClass()得到反射類
		S2GetReflectClass s2GetReflectClass=new S2GetReflectClass();
		Class<?> getClassClass=s2GetReflectClass.getClass();
		System.out.println("過物件名.getClass()得到反射類:"+getClassClass.getName());
		//2.通過物件名class.forName()得到反射類
		Class<?> forNameClass=Class.forName("S1022Reflect.S2GetReflectClass");
		System.out.println("過物件名.getClass()得到反射類:"+getClassClass.getName());
		//3.通過類名.class得到反射類
		Class classClass=S2GetReflectClass.class;
		System.out.println("通過類名.class得到反射類:"+classClass.getName());
		//4.通過包裝類.TYPE得到反射類
		Class typeClass=Integer.TYPE;
		System.out.println("通過包裝類.type得到反射類:"+typeClass.getName());
	}

}

過物件名.getClass()得到反射類:S1022Reflect.S2GetReflectClass
過物件名.getClass()得到反射類:S1022Reflect.S2GetReflectClass
通過類名.class得到反射類:S1022Reflect.S2GetReflectClass
通過包裝類.type得到反射類:int

4.動態建立物件

1.通過Class的newInstance()方法

​ 執行無參構造方法建立該類的例項

2.通過constructor的newInstance()方法

​ 使用Class物件獲取指定的Constructor物件

​ 再呼叫Constructor物件newInstance()方法建立該Class物件 對應類的物件

public class S3DynamicCreate {
	public int id;
	public String name;
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public S3DynamicCreate(int id, String name) {
		this.id = id;
		this.name = name;
	}
	
	public S3DynamicCreate() {
	}
	
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> c=Class.forName("S1022Reflect.S3DynamicCreate");
		Constructor cons=c.getConstructor(new Class[]{int.class,String.class});
		S3DynamicCreate dynamicCreate=(S3DynamicCreate) cons.newInstance(1,"lisi");
		System.out.println(dynamicCreate.id+"\t"+dynamicCreate.name);	
	}
}

1	lisi

5.呼叫反射類方法

Method getMethod(String name,Class<?>…parameterTypes) 返回一個Method物件

Object invoke(Object obj,Object…args) 對帶有指定引數的指定物件呼叫此Method物件表示底層的方法

public class S4InvokeFunction {
	public int fun(int id,String name){
		System.out.println("呼叫fun方法");
		return 10;
	}
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		Class<?> c=S4InvokeFunction.class;
		Object obj=c.newInstance();
		Method m=c.getMethod("fun", new Class[]{int.class,String.class});
		Object o=m.invoke(obj,new Object[]{1,"aa"});	
		System.out.println("o:"+o);
	}
}

6.反射的特點

優點

反射提高了Java程式的靈活性和擴充套件性,提高自適應能力,允許程式建立和控制任何類的物件,無需提前編碼目標類

缺點

反射是一種解釋操作,用於欄位和方法接入是遠慢於程式碼,主要應用在靈活性和擴充套件性要求很高的系統框架

使用反射會模糊程式內部邏輯,反射繞開和原始碼的技術,比相應的直接程式碼更復雜

相關文章