Java的反射機(jī)制之獲取class詳解
Class類基本介紹
在Java語言中,每個(gè)對(duì)象都有一個(gè)運(yùn)行時(shí)類,即其所屬的類。而這個(gè)運(yùn)行時(shí)類在Java中是以Class類的實(shí)例形式存在的,該Class類實(shí)例就是所謂的Class對(duì)象。Class類表示一個(gè)類或接口的元數(shù)據(jù),通過它可以獲取到類或接口的構(gòu)造函數(shù)、方法、字段、注解等信息,也能夠創(chuàng)建對(duì)象、調(diào)用方法等。
1.Class也是類,因此也繼承Obiect類
2.Class類對(duì)象不是new出來的,而是系統(tǒng)創(chuàng)建的
3.對(duì)于某個(gè)類的Class類對(duì)象,在內(nèi)存中只有一份,因?yàn)轭愔患虞d一次
4.每個(gè)類的實(shí)例都會(huì)記得自己是由哪個(gè) Class 實(shí)例所生成
5.通過Class對(duì)象可以完整地得到一個(gè)類的完整結(jié)構(gòu),通過一系列API
6.Class對(duì)象是存放在堆的
7.類的字節(jié)碼二進(jìn)制數(shù)據(jù),是放在方法區(qū)的,有的地方稱為類的元數(shù)據(jù)(包括 方法代碼變量名,方法名,訪問權(quán)限等等)
代碼演示:
package com.reflection.class_;
/**
* 對(duì)Class類特點(diǎn)的梳理
*/
public class Class01 {
public static void main(String[] args) throws ClassNotFoundException {
//看看Class類圖
//1. Class也是類,因此也繼承Object類
//Class
//2. Class類對(duì)象不是new出來的,而是系統(tǒng)創(chuàng)建的
//(1) 傳統(tǒng)new對(duì)象
/* ClassLoader類
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
*/
//Cat cat = new Cat();
//(2) 反射方式, 沒有debug到 ClassLoader類的 loadClass, 原因是,我沒有注銷Cat cat = new Cat();
/*
ClassLoader類, 仍然是通過 ClassLoader類加載Cat類的 Class對(duì)象
public Class<?> loadClass(String name) throws ClassNotFoundException {
return loadClass(name, false);
}
*/
Class cls1 = Class.forName("com.Cat");
//3. 對(duì)于某個(gè)類的Class類對(duì)象,在內(nèi)存中只有一份,因?yàn)轭愔患虞d一次
Class cls2 = Class.forName("com.Cat");
System.out.println(cls1.hashCode());
System.out.println(cls2.hashCode());
Class cls3 = Class.forName("com.Dog");
System.out.println(cls3.hashCode());
}
}- forName(String className):根據(jù)類的全限定名獲取對(duì)應(yīng)的類對(duì)象。
- newInstance():創(chuàng)建一個(gè)類的對(duì)象,要求該類必須具有默認(rèn)的構(gòu)造方法。
- getConstructor(Class<?>… parameterTypes):獲取指定參數(shù)類型的構(gòu)造方法。
- getDeclaredConstructor(Class<?>… parameterTypes):獲取該類中聲明的指定參數(shù)類型的構(gòu)造方法,即使該構(gòu)造方法是私有的也可以獲取到。
- getMethod(String name, Class<?>… parameterTypes):獲取指定方法名和參數(shù)類型的公有方法。
- getDeclaredMethod(String name, Class<?>… parameterTypes):獲取該類中聲明的指定方法名稱和參數(shù)類型的方法,即使該方法是私有的也可以獲取到。
- getField(String name):獲取指定名稱的公有字段。
- getDeclaredField(String name):獲取該類中聲明的指定名稱的字段,即使該字段是私有的也可以獲取到。
代碼演示:
package com.reflection.class_;
import com.Car;
import java.lang.reflect.Field;
/**
* 演示Class類的常用方法
*/
public class Class02 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
String classAllPath = "com.Car";
//1 . 獲取到Car類 對(duì)應(yīng)的 Class對(duì)象
//<?> 表示不確定的Java類型
Class<?> cls = Class.forName(classAllPath);
//2. 輸出cls
System.out.println(cls); //顯示cls對(duì)象, 是哪個(gè)類的Class對(duì)象 com.Car
System.out.println(cls.getClass());//輸出cls運(yùn)行類型 java.lang.Class
//3. 得到包名
System.out.println(cls.getPackage().getName());//包名
//4. 得到全類名
System.out.println(cls.getName());
//5. 通過cls創(chuàng)建對(duì)象實(shí)例
Car car = (Car) cls.newInstance();
System.out.println(car);//car.toString()
//6. 通過反射獲取屬性 brand
Field brand = cls.getField("brand");
System.out.println(brand.get(car));//寶馬
//7. 通過反射給屬性賦值
brand.set(car, "奔馳");
System.out.println(brand.get(car));//奔馳
//8 我希望大家可以得到所有的屬性(字段)
System.out.println("=======所有的字段屬性====");
Field[] fields = cls.getFields();
for (Field f : fields) {
System.out.println(f.getName());//名稱
}
}
}
如何獲取class類對(duì)象
1.前提: 已知一個(gè)類的全類名,且該類在類路徑下,可通過Class類的靜態(tài)方法forName0獲取,可能拋出ClassNotFoundException,實(shí)例: Class cls1Class.forName("iava.lana.Cat”):
應(yīng)用場(chǎng)景:多用于配置文件,讀取類全路徑,加載類
2.前提:若已知具體的類,通過類的class 獲取,該方式 最為安全可靠,程序性能最高實(shí)例: Class cls2 = Catclass;
應(yīng)用場(chǎng)景:多用于參數(shù)傳遞,比如通過反射得到對(duì)應(yīng)構(gòu)造器對(duì)象
3.前提: 已知某個(gè)類的實(shí)例,調(diào)用該實(shí)例的getClass(方法獲取Class對(duì)象,實(shí)例Class clazz = 對(duì)象getClass0://運(yùn)行類型
應(yīng)用場(chǎng)景: 通過創(chuàng)建好的對(duì)象,獲取Class對(duì)象
4.其他方式ClassLoader cl = 對(duì)象.getClass().getClassLoader();
Class clazz4=cl.loadClass("類的全類目");
5.基本數(shù)據(jù)(int, char,boolean,float,double,byte,long,short) 按如下方式得到Class類對(duì)象
6.基本數(shù)據(jù)類型對(duì)應(yīng)的包裝類,可以通過 .type 得到Class類對(duì)象
代碼演示:
package com.reflection.class_;
import com.Car;
/**
* 演示得到Class對(duì)象的各種方式(6)
*/
public class GetClass_ {
public static void main(String[] args) throws ClassNotFoundException {
//1. Class.forName
String classAllPath = "com.Car"; //通過讀取配置文件獲取
Class<?> cls1 = Class.forName(classAllPath);
System.out.println(cls1);
//2. 類名.class , 應(yīng)用場(chǎng)景: 用于參數(shù)傳遞
Class cls2 = Car.class;
System.out.println(cls2);
//3. 對(duì)象.getClass(), 應(yīng)用場(chǎng)景,有對(duì)象實(shí)例
Car car = new Car();
Class cls3 = car.getClass();
System.out.println(cls3);
//4. 通過類加載器【4種】來獲取到類的Class對(duì)象
//(1)先得到類加載器 car
ClassLoader classLoader = car.getClass().getClassLoader();
//(2)通過類加載器得到Class對(duì)象
Class cls4 = classLoader.loadClass(classAllPath);
System.out.println(cls4);
//cls1 , cls2 , cls3 , cls4 其實(shí)是同一個(gè)對(duì)象
System.out.println(cls1.hashCode());
System.out.println(cls2.hashCode());
System.out.println(cls3.hashCode());
System.out.println(cls4.hashCode());
//5. 基本數(shù)據(jù)(int, char,boolean,float,double,byte,long,short) 按如下方式得到Class類對(duì)象
Class<Integer> integerClass = int.class;
Class<Character> characterClass = char.class;
Class<Boolean> booleanClass = boolean.class;
System.out.println(integerClass);//int
//6. 基本數(shù)據(jù)類型對(duì)應(yīng)的包裝類,可以通過 .TYPE 得到Class類對(duì)象
Class<Integer> type1 = Integer.TYPE;
Class<Character> type2 = Character.TYPE; //其它包裝類BOOLEAN, DOUBLE, LONG,BYTE等待
System.out.println(type1);
System.out.println(integerClass.hashCode());//?
System.out.println(type1.hashCode());//?
}
}哪些類型有Class對(duì)象
1.外部類,成員內(nèi)部類,靜態(tài)內(nèi)部類,局部內(nèi)部類,匿名內(nèi)部類
2interface : 接口
3.數(shù)組
4.enum:枚舉
5.annotation:注解
6.基本數(shù)據(jù)類型
7.void
代碼演示:
package com.reflection.class_;
import java.io.Serializable;
/**
* 演示哪些類型有Class對(duì)象
*/
public class AllTypeClass {
public static void main(String[] args) {
Class<String> cls1 = String.class;//外部類
Class<Serializable> cls2 = Serializable.class;//接口
Class<Integer[]> cls3 = Integer[].class;//數(shù)組
Class<float[][]> cls4 = float[][].class;//二維數(shù)組
Class<Deprecated> cls5 = Deprecated.class;//注解
//枚舉
Class<Thread.State> cls6 = Thread.State.class;
Class<Long> cls7 = long.class;//基本數(shù)據(jù)類型
Class<Void> cls8 = void.class;//void數(shù)據(jù)類型
Class<Class> cls9 = Class.class;//
System.out.println(cls1);
System.out.println(cls2);
System.out.println(cls3);
System.out.println(cls4);
System.out.println(cls5);
System.out.println(cls6);
System.out.println(cls7);
System.out.println(cls8);
System.out.println(cls9);
}
}到此這篇關(guān)于Java的反射機(jī)制之獲取class詳解的文章就介紹到這了,更多相關(guān)Java的反射機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Javassist之一秒理解java動(dòng)態(tài)編程
概述Javassist是一款字節(jié)碼編輯工具,可以直接編輯和生成Java生成的字節(jié)碼,以達(dá)到對(duì).class文件進(jìn)行動(dòng)態(tài)修改的效果。2019-06-06
Java 實(shí)戰(zhàn)練習(xí)之網(wǎng)上電商項(xiàng)目的實(shí)現(xiàn)
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+vue+Springboot+ssm+mysql+maven+redis實(shí)現(xiàn)一個(gè)網(wǎng)上電商項(xiàng)目,大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
Java中減少if-else的設(shè)計(jì)模式和優(yōu)化技巧
“過于依賴 if-else 不僅會(huì)讓代碼變得臃腫不堪,還會(huì)使維護(hù)成本大大增加,其實(shí),if-else 雖然是最基礎(chǔ)的條件分支,但它并不是萬能的解決方案,今天,我將帶大家了解一些取代 if-else 的設(shè)計(jì)模式和優(yōu)化技巧,需要的朋友可以參考下2025-04-04
Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)項(xiàng)目之倉庫管理系統(tǒng)的實(shí)現(xiàn)流程
這是一個(gè)使用了java+SSM+Maven+Bootstrap+mysql開發(fā)的倉庫管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有一個(gè)倉庫管理系統(tǒng)該有的所有功能,感興趣的朋友快來看看吧2022-01-01
javax.mail.SendFailedException: Sending failed問題原因
這篇文章主要介紹了javax.mail.SendFailedException: Sending failed問題原因,需要的朋友可以參考下2015-05-05

