Java的反射機制是什么以及是如何獲取反射的,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
加載完類之后,在堆內存的方法區中就產生了一個Class類型的對象 ,一個類只有一個Class對象,這個對象就包含了完整的類的結構信息。我們可以通過這個對象看到類的結構。這個對象就像一面鏡子,通過這個鏡子可以看到類的結構,所以我們形象的稱為:反射 ,或者說動態(運行時)獲取類信息和調用類方法
想要去實現反射想要借助一些類分別是 class,Constructor,Field,Method;
吃飯的先拿碗筷,反射就得先找先找 Class
找Class的有三種方式
1實例化對象獲取該實例的 Class 對象
Person person = new Student();
Class s=person.getClass();
2通過類的全限定名獲取該類的 Class 對象
Class s1 =Class.forName(“com.ma.reflect.Student”);
3通過類名.class
Class S2=Student.class;
代碼案例
package com.ma.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class reflectTest6 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { //反射 Class c=Class.forName("com.ma.reflect.User"); System.out.println("獲得包+類"+c.getName());//獲得包+類 System.out.println("獲得類名"+c.getSimpleName());//獲得類名 //獲得類的屬性 System.out.println("-------------------------"); Field[] fields=c.getFields();//的到public類 for (Field field : fields) { System.out.println("獲得類的Public 屬性"+field); } System.out.println("-------------------------"); //獲得全部的類屬性 Field[] f1=c.getDeclaredFields(); for (Field field : f1) { System.out.println("獲得類的全部屬性"+field); } System.out.println("-------------------------"); //獲得指定屬性的值 Field name=c.getDeclaredField("age"); System.out.println("獲得指定了屬性的類型"+name); System.out.println("-------------------------"); //獲得指定方法的值 Method[] methods=c.getMethods(); System.out.println("獲得所有的public方法"); for (Method method : methods) { System.out.println("public類有"+method); } Method[] methods1=c.getDeclaredMethods(); System.out.println("獲得所有的public方法"); for (Method method : methods1) { System.out.println("所有的方法="+method); } System.out.println("-------------------------"); System.out.println("獲得所有的public構造器"); Constructor[] constructors=c.getConstructors(); for (Constructor constructor : constructors) { System.out.println("public的構造器"+constructor); } System.out.println("獲得所有的構造器"); Constructor[] constructors1=c.getDeclaredConstructors(); for (Constructor constructor : constructors1) { System.out.println("所有的構造器"+constructor); } } }
Class user=Class.forName("com.ma.reflect.User");//獲得Class對象 //構造對象 User user1=(User) user.newInstance();//無參方法 System.out.println(user1); //通過構造器 創建有參方法 Constructor constructor=user.getDeclaredConstructor(String.class,int.class,int.class); User user2= (User) constructor.newInstance("myt",28,213); System.out.println(user2);
Class user=Class.forName("com.ma.reflect.User");//獲得Class對象 User user3=(User) user.newInstance(); //通反射去獲取一個方法 Method setName=user.getDeclaredMethod("setName", String.class); //invoke激活 (對象,參數) setName.invoke(user3,"myt"); System.out.println(user3.getName());
//通過反射去調用方法
User user4=(User) user.newInstance(); Field name=user.getDeclaredField("name");//得到屬性 //***修改權限 去實現對私有屬性的修改 通過關閉程序的安全監測 name.setAccessible(true); name.set(user4,"tym"); //private的屬性無法直接去調用并且修改 System.out.println(user4.getName());
普通方法、反射、關閉安全檢測的反射
public class reflectTest8 { //普通方法調用 public static void test(){ User user=new User(); Long startTime=System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { user.getName(); } Long endTime=System.currentTimeMillis(); System.out.println("普通方法"+(endTime-startTime)+"ms"); } //反射方法調用 public static void test1() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user=new User(); Class c=Class.forName("com.ma.reflect.User"); Method getName=c.getDeclaredMethod("getName",null); Long startTime=System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { getName.invoke(user,null); } Long endTime=System.currentTimeMillis(); System.out.println("反射方法"+(endTime-startTime)+"ms"); } //反射方法 關閉檢測調用 public static void test2() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user=new User(); Class c=Class.forName("com.ma.reflect.User"); Method getName=c.getDeclaredMethod("getName",null); getName.setAccessible(true); Long startTime=System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { getName.invoke(user,null); } Long endTime=System.currentTimeMillis(); System.out.println("反射方法 關閉檢測"+(endTime-startTime)+"ms"); } public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { test(); test1(); test2(); } }
反射提高了Java程序的靈活性和擴展性,降低耦合性,提高自適應能力。它允許程序創建和控制任何類的對象,無需提前硬編碼目標類
因為是JVM操作,所以對于性能來說會有所下降。
容易對程序源碼造成一定的混亂。
在編譯時根本無法知道該對象或類可能屬于哪些類,程序只依靠運行時信息來發現該對象和類的真實信息
關于Java的反射機制是什么以及是如何獲取反射的問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。