獲取Java加載器和類完整結(jié)構(gòu)的方法分享
類加載器的作用與類緩存
類加載器的作用:將class文件字節(jié)碼內(nèi)容加載到內(nèi)存中,并將這些靜態(tài)數(shù)據(jù)轉(zhuǎn)換成方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu),然后在堆中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,作為方法區(qū)中類數(shù)據(jù)的訪問入口。
類緩存:標(biāo)準(zhǔn)的JavaSE類加載器可以按要求查找類,但一旦某個(gè)類被加載到類加載器中,它將維持加載(緩存)一段時(shí)間。不過JVM垃圾回收機(jī)制可以回收這些Class對(duì)象

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)類加載器的父類加裁器-->擴(kuò)展類加裁器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//獲取擴(kuò)展類加載器的父類加裁器-->根加裁器(c/c++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//測(cè)試當(dāng)前美是哪個(gè)加載器加裁的
ClassLoader classLoader = Class.forName("Collections.text1").getClassLoader();
System.out.println(classLoader);
//測(cè)試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
------[省略]
獲取運(yùn)行時(shí)類的完整結(jié)構(gòu)
通過反射獲取運(yùn)行時(shí)類的完整結(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
注:在獲得指定屬性的值時(shí),一定要使用getDeclaredField()方法,而不能使用getFields(),因?yàn)間etFields只能獲取到公共屬性
獲取類的方法和構(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è)構(gòu)造器
Constructor declaredConstructors=c1.getDeclaredConstructor(String.class,int.class, String.class, String.class);
System.out.println("指定的某一個(gè)構(gòu)造器:"+declaredConstructors);
}
}獲取Class對(duì)象的作用
創(chuàng)建類的對(duì)象:調(diào)用Class對(duì)象的newlnstance()方法
1:類必須有一個(gè)無參數(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對(duì)象
Class c1 = Class.forName("Collections.person");
//構(gòu)造一個(gè)對(duì)象
person user = (person)c1.newInstance();
//本質(zhì)是調(diào)用了類的無參構(gòu)造器
System.out.println(user);
}
}
報(bào)錯(cuò):
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對(duì)象的newlnstance()方法去創(chuàng)建類的對(duì)象
難道沒有無參的構(gòu)造器就不能創(chuàng)建對(duì)象了嗎?
答案當(dāng)然不是如此,只要在操作的時(shí)候明確的調(diào)用類中的構(gòu)造器并將參數(shù)傳遞進(jìn)去之后,才可以實(shí)例化操作。
步驟如下:
1)通過Class類的getDeclaredConstructor(Class ... parameterTypes)
取得本類的指定形參類型的構(gòu)造器
2)向構(gòu)造器的形參中傳遞一個(gè)對(duì)象數(shù)組進(jìn)去,里面包含了構(gòu)造器中所需的各個(gè)參數(shù)
3)通過Constructor實(shí)例化對(duì)象
舉例:
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對(duì)象
Class c1 = Class.forName("Collections.person");
//通過構(gòu)造器創(chuàng)建對(duì)象
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)的方法分享的詳細(xì)內(nèi)容,更多關(guān)于Java加載器 類完整結(jié)構(gòu)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決java 查看JDK中底層源碼的實(shí)現(xiàn)方法
本篇文章是對(duì)在java中查看JDK中底層源碼的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Java基于jdbc實(shí)現(xiàn)的增刪改查操作示例
這篇文章主要介紹了Java基于jdbc實(shí)現(xiàn)的增刪改查操作,結(jié)合實(shí)例形式分析了java使用jdbc進(jìn)行數(shù)據(jù)庫的連接、增刪改查等基本操作技巧,需要的朋友可以參考下2019-01-01
spring動(dòng)態(tài)控制定時(shí)任務(wù)的實(shí)現(xiàn)
在實(shí)際項(xiàng)目中,經(jīng)常需要?jiǎng)討B(tài)的控制定時(shí)任務(wù),比如通過接口增加、啟動(dòng)、停止、刪除定時(shí)任務(wù),本文主要介紹了spring動(dòng)態(tài)控制定時(shí)任務(wù)的實(shí)現(xiàn),感興趣的可以了解一下2024-01-01
SpringCloud項(xiàng)目中集成Sentinel問題
在SpringCloud項(xiàng)目中集成Sentinel,可以實(shí)現(xiàn)流量控制、熔斷降級(jí)等功能,提升系統(tǒng)穩(wěn)定性和可用性,集成步驟包括添加Sentinel依賴、配置控制臺(tái)地址、啟動(dòng)控制臺(tái)、配置限流熔斷規(guī)則、使用注解和集成SpringCloudGateway,這有助于處理高并發(fā)場景,保護(hù)服務(wù)穩(wěn)定運(yùn)行2024-10-10
Spring Cache和EhCache實(shí)現(xiàn)緩存管理方式
這篇文章主要介紹了Spring Cache和EhCache實(shí)現(xiàn)緩存管理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
spring項(xiàng)目如何配置多數(shù)據(jù)源(已上生產(chǎn),親測(cè)有效)
這篇文章主要介紹了spring項(xiàng)目如何配置多數(shù)據(jù)源(已上生產(chǎn),親測(cè)有效),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

