獲取Java加載器和類完整結(jié)構(gòu)的方法分享
類加載器的作用與類緩存
類加載器的作用:將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu),然后在堆中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)中類數(shù)據(jù)的訪問入口。
類緩存:標準的JavaSE類加載器可以按要求查找類,但一旦某個類被加載到類加載器中,它將維持加載(緩存)一段時間。不過JVM垃圾回收機制可以回收這些Class對象
JVM 規(guī)范定義了如下類型的類的加載器:
獲取加載器的方法
package Collections; public class text1 { public static void main(String[] args) throws ClassNotFoundException { //獲取系統(tǒng)類的加載器 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //獲取系統(tǒng)類加載器的父類加裁器-->擴展類加裁器 ClassLoader parent = systemClassLoader.getParent(); System.out.println(parent); //獲取擴展類加載器的父類加裁器-->根加裁器(c/c++) ClassLoader parent1 = parent.getParent(); System.out.println(parent1); //測試當前美是哪個加載器加裁的 ClassLoader classLoader = Class.forName("Collections.text1").getClassLoader(); System.out.println(classLoader); //測試JDK內(nèi)置的類是誰加載的 classLoader = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader); //如何獲得系統(tǒng)類加截哭可以加裁的路徑 System.out.println(System.getProperty("java.class.path")); } }
輸出:
jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
jdk.internal.loader.ClassLoaders$PlatformClassLoader@15aeb7ab
null
jdk.internal.loader.ClassLoaders$AppClassLoader@78308db1
null
------[省略]
獲取運行時類的完整結(jié)構(gòu)
通過反射獲取運行時類的完整結(jié)構(gòu)
Field、Method、Constructor、Superclass、Interface、Annotation
獲得有關(guān)類自身的信息
package Collections; import java.lang.reflect.Field; ???????public class text1 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1 = Class.forName("Collections.person"); //獲得類的名字 System.out.println(c1.getName()); //獲得包名 +類名System.out.println(cl.getSimpleName()); //獲得類名 //獲得類的屬性 System.out.println("==================================="); Field[] fields = c1.getFields(); //只能找到public屬性 fields = c1.getDeclaredFields(); //我到全部的屬性 for (Field field : fields) { System.out.println(field); } System.out.println("==================================="); //獲得指定屬性的值 Field name = c1.getDeclaredField("name"); System.out.println(name); } }
輸出:
Collections.person
===================================
java.lang.String Collections.person.name
int Collections.person.age
java.lang.String Collections.person.sex
java.lang.String Collections.person.city
===================================
java.lang.String Collections.person.name
注:在獲得指定屬性的值時,一定要使用getDeclaredField()方法,而不能使用getFields(),因為getFields只能獲取到公共屬性
獲取類的方法和構(gòu)造器的信息
package Collections; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; ???????public class text1 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("Collections.person"); Method[] methods = c1.getMethods(); //獲得本類及其父類的全部public方法 for (Method method : methods) { System.out.println("正常的:"+method); } methods = c1.getDeclaredMethods();//獲得本類的所有方以 for (Method method : methods) { System.out.println("getDeclaredMethods:"+method); } //獲得指定方法 //重載 Method getName = c1.getMethod("getName", null) ; Method setName =c1.getMethod("setName", String.class) ; System.out.println(getName);System.out.println(setName); //獲得指定的構(gòu)造器 System.out.println("==================================="); Constructor[] constructors = c1.getConstructors();//獲得public方法 for (Constructor constructor : constructors) { System.out.println(constructor); constructors = c1.getDeclaredConstructors();//獲得所有方法 for (Constructor constructor1 : constructors) { System.out.println("#" + constructor1); } } //指定的某一個構(gòu)造器 Constructor declaredConstructors=c1.getDeclaredConstructor(String.class,int.class, String.class, String.class); System.out.println("指定的某一個構(gòu)造器:"+declaredConstructors); } }
獲取Class對象的作用
創(chuàng)建類的對象:調(diào)用Class對象的newlnstance()方法
1:類必須有一個無參數(shù)的構(gòu)造器
2:類的構(gòu)造器的訪問權(quán)限需要足夠
舉例:
package Collections; public class person_text { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException { //獲得Class對象 Class c1 = Class.forName("Collections.person"); //構(gòu)造一個對象 person user = (person)c1.newInstance(); //本質(zhì)是調(diào)用了類的無參構(gòu)造器 System.out.println(user); } }
報錯:
Exception in thread "main" java.lang.InstantiationException: Collections.person
at java.base/java.lang.Class.newInstance(Class.java:671)
at Collections.person_text.main(person_text.java:8)
Caused by: java.lang.NoSuchMethodException: Collections.person.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3617)
at java.base/java.lang.Class.newInstance(Class.java:658)
... 1 more
由于person中沒有無參構(gòu)造器,因此,我們無法通過調(diào)用Class對象的newlnstance()方法去創(chuàng)建類的對象
難道沒有無參的構(gòu)造器就不能創(chuàng)建對象了嗎?
答案當然不是如此,只要在操作的時候明確的調(diào)用類中的構(gòu)造器并將參數(shù)傳遞進去之后,才可以實例化操作。
步驟如下:
1)通過Class類的getDeclaredConstructor(Class ... parameterTypes)
取得本類的指定形參類型的構(gòu)造器
2)向構(gòu)造器的形參中傳遞一個對象數(shù)組進去,里面包含了構(gòu)造器中所需的各個參數(shù)
3)通過Constructor實例化對象
舉例:
package Collections; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class person_text { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { //獲得Class對象 Class c1 = Class.forName("Collections.person"); //通過構(gòu)造器創(chuàng)建對象 Constructor constructor = c1.getDeclaredConstructor(String.class, int.class,String.class, String.class); person user2 = (person)constructor.newInstance("Lisa",19,"女","北京"); System.out.println(user2); } }
輸出:
person{name='Lisa', age=19, sex='女', city='北京'}
以上就是獲取Java加載器和類完整結(jié)構(gòu)的方法分享的詳細內(nèi)容,更多關(guān)于Java加載器 類完整結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
mybatis報錯?resultMapException的解決
這篇文章主要介紹了mybatis報錯?resultMapException的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01SpringBoot中的靜態(tài)資源訪問的實現(xiàn)
這篇文章主要介紹了SpringBoot中的靜態(tài)資源訪問的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-09-09詳解java數(shù)據(jù)結(jié)構(gòu)與算法之雙鏈表設(shè)計與實現(xiàn)
本篇文章主要介紹了詳解java數(shù)據(jù)結(jié)構(gòu)與算法之雙鏈表設(shè)計與實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06動態(tài)更改Spring定時任務(wù)Cron表達式的優(yōu)雅方案實例詳解
spring定時器非常強大,但是有時候我們需要在不需要重啟應(yīng)用就可以動態(tài)的改變Cron表達式的值,下面這篇文章主要給大家介紹了關(guān)于動態(tài)更改Spring定時任務(wù)Cron表達式的優(yōu)雅方案,需要的朋友可以參考下2022-12-12springboot整合swagger3和knife4j的詳細過程
knife4j的前身是swagger-bootstrap-ui,取名knife4j是希望她能像一把匕首一樣小巧,輕量,并且功能強悍,下面這篇文章主要介紹了springboot整合swagger3和knife4j的詳細過程,需要的朋友可以參考下2022-11-11java使用@Scheduled注解執(zhí)行定時任務(wù)
這篇文章主要給大家介紹了關(guān)于java使用@Scheduled注解執(zhí)行定時任務(wù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01通過JDBC連接oracle數(shù)據(jù)庫的十大技巧
通過JDBC連接oracle數(shù)據(jù)庫的十大技巧...2006-12-12java不同版本在多線程中使用隨機數(shù)生成器的實現(xiàn)
本文主要介紹了java不同版本在多線程中使用隨機數(shù)生成器的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04