日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

21、java中的反射机制

發(fā)布時間:2023/12/3 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 21、java中的反射机制 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

先推薦安裝一個 eclipse 的反編譯插件? Enhanced Class Decompiler

是什么?

?????? 在說反射之前先說一下編譯時類型和運行時類型,大家都知道List是一個接口,它是不可以被實例化的,但是可以通過多態(tài)實現(xiàn):List list = new ArrayList(); 對于變量list來說編譯時期他被聲明為List類型,但是真正使用的確實ArrayList中的成員(在堆中創(chuàng)建的是ArrayList的對象),所以list的運行時類型是ArrayList,它的運行時類就是ArrayList被編譯之后加載到內(nèi)存的字節(jié)碼類文件。

?????? 再說反射,反射是java中一種可以在執(zhí)行期間獲取類內(nèi)部信息的技術(shù),說白一點就是根據(jù)加載的類字節(jié)碼文件去獲取類本身的一種技術(shù),之前介紹了類加載,加載過程中會創(chuàng)建一個Class類的對象來表示這個類,每一個Class類的對象都是一個運行時類,所以反射就是根據(jù)運行時類獲取其本類信息并使用這個類的一種技術(shù),反射號稱是java實現(xiàn)動態(tài)編程的關(guān)鍵。為什么說反射是實現(xiàn)動態(tài)編程的關(guān)鍵呢?我自己的理解是這樣的:假設(shè)我寫了一個方法用于處理很多類,這個時候呢,我不可能為每一個類都寫一個方法,可是呢,我知道每一個運行時類都是Class的對象,并且我可以根據(jù)class對象獲取其本類的對象,所以這個時候,我接受的參數(shù)就可以是一個Class類型的參數(shù),這樣就使得代碼可以高度復(fù)用了,這就是反射的魅力。通過使用反射,可以使得代碼高度復(fù)用,大大的降低代碼的耦合性。

有什么用?

?????? 具體說一下反射的能力:使用反射可以在運行時判斷任意一個對象所屬的類、構(gòu)造一個類的對象、判斷一個類具有的成員變量和方法、用一個對象的成員變量和方法等等。通過使用反射可以通過運行時類去操作類本身的所有屬性。

怎么用?

????? 想要使用反射,就要獲取運行時類,那么運行時類如何獲取和表示呢?在java中每一個運行時類都是java.lang.Class的對象,所以可以使用Class來聲明運行時類,而獲取運行時類的方式有四種,代碼如下:

public static void main(String[] args) {//1、通過類的.class屬性Class<User> c1 = User.class;//2、通過類對象的.getClass方法User user = new User();Class c2 = user.getClass();//3、通過Class類的forName方法,一般用這個try {Class c3 = Class.forName("com.czp.reflection.User");} catch (ClassNotFoundException e) {e.printStackTrace();}//4、通過類的加載器獲取(這種一般用的不多)try {Class<?> c4 = ClassLoader.getSystemClassLoader().loadClass("com.czp.reflection.User");} catch (ClassNotFoundException e) {e.printStackTrace();} }

????? 這里需要說明的一點是,在一個進程中,一個類的字節(jié)碼文件添加到內(nèi)存中后就是一個運行時類,每個運行時類只會加載一次。

????? 獲取了運行時類也就是Class的對象之后可以做些什么呢?如何利用反射?下邊具體說一下

獲取類的構(gòu)造方法、創(chuàng)建類的對象:

public class ReflectionTest {public static void main(String[] args) {ReflectionTest test = new ReflectionTest();test.getClassConstructors();}//獲取User的運行時類 @SuppressWarnings("unchecked") public Class<User> getUser() {String name = "com.czp.reflection.User";Class<User> user= null;try {user = (Class<User>) Class.forName(name);} catch (ClassNotFoundException e) {e.printStackTrace();}return user; } //測試獲取類中的構(gòu)造方法,創(chuàng)建類的實例 public void getClassConstructors() {try{Class<User> userClass = getUser();//1、直接調(diào)用Class中方法創(chuàng)建類的對象,這種方法的前提是類中必須要有一個公共的無參構(gòu)造方法User user = userClass.newInstance();//2、通過類中對應(yīng)的構(gòu)造方法創(chuàng)建對象// 首先就需要先獲取這個類中的構(gòu)造方法//Declared 有聲明之意,可理解為只要是聲明的構(gòu)造方法都可以獲取到,獲取所有構(gòu)造方法(不管權(quán)限如何)Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors();//只能獲取所有公共的構(gòu)造方法Constructor<?>[] constructors = userClass.getConstructors();//獲取指定參數(shù)的構(gòu)造方法(所有的)Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);//如果構(gòu)造方法是私有的,通過setAccessible(true)設(shè)置可以使用私有構(gòu)造方法進行創(chuàng)建對象declaredConstructor.setAccessible(true);User privateUser = declaredConstructor.newInstance("zhangsan");//User [name=zhangsan, age=null]System.out.println(privateUser);//獲取指定參數(shù)的構(gòu)造方法(共有的)Constructor<User> constructor = userClass.getConstructor(Integer.class);//再根據(jù)構(gòu)造方法創(chuàng)建類的對象User user2 = constructor.newInstance(5);//User [name=null, age=5]}catch (Exception e) {e.printStackTrace();} } }

獲取運行時類的成員:

//測試獲取類中的成員信息 public void getClassMethods() {try{Class<User> userClass = getUser();User user = userClass.newInstance();//---------------------------處理方法----------------------////1、獲取所有的方法Method[] declaredMethods = userClass.getDeclaredMethods();//2、根據(jù)方法的名稱參數(shù)獲取方法Method declaredMethod = userClass.getDeclaredMethod("show");//使用方法,如果是私有方法則先強制設(shè)置以下declaredMethod.setAccessible(true);declaredMethod.invoke(user, null);//3、獲取所有公共的方法(包括父類的)Method[] methods = userClass.getMethods();//4、獲取方法,不寫了,就是根據(jù)名字獲取,和上邊一樣//---------------------------處理變量----------------------////1、獲取所有變量Field[] declaredFields = userClass.getDeclaredFields();//2、獲取指定變量Field declaredField = userClass.getDeclaredField("name");declaredField.setAccessible(true);declaredField.set(user, "zhangsan");System.out.println(declaredField.get(user));//zhangsan//3、還有兩個獲取所有共有的變量}catch (Exception e) {e.printStackTrace();} }

獲取運行時類的其他:

public void getClassOther(){try{Class<User> userClass = getUser();User user = userClass.newInstance();//1、可以獲取注解Annotation[] declaredAnnotations = userClass.getDeclaredAnnotations();//2、所在包名Package p = userClass.getPackage();//3、獲取父類Class<? super User> superclass = userClass.getSuperclass();//4、獲取實現(xiàn)的接口Class<?>[] interfaces = userClass.getInterfaces();//還有其他,查看API}catch (Exception e) {e.printStackTrace();} }

?

總結(jié)

以上是生活随笔為你收集整理的21、java中的反射机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。