一、概念
1.反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法。
2.反射可以在一個類運行的時候獲取類的信息的機制,可以獲取在編譯期不可能獲得的類的信息。
3.對於任意一個對象,都能調用它的任意一個方法和屬性(private:落魄了,家人們)。
4.因為類的信息是保存在Class對象中的,而這個Class對象是在程序運行時被類加載器(ClassLoader)動態加載的。
5.當類加載器裝載運行了類后,動態獲取Class對象的信息以及動態操作Class對象的屬性和方法的功能稱為Java語音的反射機制。
二、作用
1.反編譯:.class —> .java。
2.通過反射機制訪問Java對象中的屬性、方法、構造方法等。
三、原理
利用加載到jvm中的.class文件來進行操作,.class文件中包含java類的所有信息,當你不知道某個類具體信息時,可以使用反射獲取class,然后進行各種操作。
在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。
總結說:反射就是把java類中的各種成分映射成一個個的Java對象,並且可以進行操作。
四、獲取class的三種方法
List<Class> classList=new ArrayList<Class>(); //獲取class的三種方式 //1.通過對象調用getClass()方法獲取 classList.add(human.getClass()); //2.通過類名.class獲取(ps:所有類都有一個隱含的靜態的成員變量class)。首選方法,安全可靠性能高 classList.add(Human.class); //3.通過CLass類的靜態方法forName()獲取,注意該方法可能拋出ClassNotFound異常 classList.add(Class.forName("reflex.Human")); System.out.println(classList.toString());
五、Class類的主要方法
getName():獲得類的完整名字。
getFields():獲得類的public類型的屬性。
getDeclaredFields():獲得類的所有屬性。包括private 聲明的和繼承類
getMethods():獲得類的public類型的方法。
getDeclaredMethods():獲得類的所有方法。包括private 聲明的和繼承類
getMethod(String name, Class[] parameterTypes):獲得類的特定方法,name參數指定方法的名字,parameterTypes 參數指定方法的參數類型。
getConstructors():獲得類的public類型的構造方法。
getConstructor(Class[] parameterTypes):獲得類的特定構造方法,parameterTypes 參數指定構造方法的參數類型。
newInstance():通過類的構造方法創建這個類的一個對象。
六、實例
public class Human { public String name; private int age=18; public static String text="---static text---"; public int getAge() { return age; } public void setAge(int age) { this.age = age; } void human(){ } private void fly(){ System.out.println("can not fly"); } public void hello(){ System.out.println("hello"); } }
public class ReflexTest { public static void main(String[] args) { System.out.println(Human.text); Human human=new Human(); try { List<Class> classList=new ArrayList<Class>(); //獲取class的三種方式 //1.通過對象調用getClass()方法獲取 classList.add(human.getClass()); //2.通過類名.class獲取(ps:所有類都有一個隱含的靜態的成員變量class)。首選方法,安全可靠性能高 classList.add(Human.class); //3.通過CLass類的靜態方法forName()獲取,注意該方法可能拋出ClassNotFound異常 classList.add(Class.forName("reflex.Human")); System.out.println(classList.toString()); System.out.println(classList.get(1).getName()); System.out.println("private:落魄了,家人們"); Field field=classList.get(1).getDeclaredField("age"); System.out.println(field); System.out.println(human.getAge()); //設置可訪問private field.setAccessible(true); //設置private變量的值 field.set(human,100); System.out.println(human.getAge()); Method privateMethod =classList.get(1).getDeclaredMethod("fly",null); privateMethod.setAccessible(true); privateMethod.invoke(human,null); System.out.println("------getFields:"); //getFields()獲取public類型的成員變量 Field[] fieldsOfPublic=classList.get(1).getFields(); for (Field i:fieldsOfPublic) { System.out.println(i); } System.out.println("------getDeclaredFields:"); //getDeclaredFields()獲取所有成員變量 Field[] fieldsAll = classList.get(1).getDeclaredFields(); for (Field j:fieldsAll) { System.out.println(j); } //getMethod(name,paramterTypes)只能獲取public類型的成員方法 Method method=classList.get(1).getMethod("hello",null); System.out.println("獲取成員方法hello--"+method); //getDeclaredMethods()獲取所有成員方法 Method[] methods=classList.get(1).getDeclaredMethods(); System.out.println("所有成員方法"); for (Method m:methods) { System.out.println(m); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
參考:
https://blog.csdn.net/qq_24549805/article/details/104013083
https://blog.csdn.net/huangliniqng/article/details/88554510