Java的反射機制之獲取class詳解
Class類基本介紹
在Java語言中,每個對象都有一個運行時類,即其所屬的類。而這個運行時類在Java中是以Class類的實例形式存在的,該Class類實例就是所謂的Class對象。Class類表示一個類或接口的元數(shù)據(jù),通過它可以獲取到類或接口的構(gòu)造函數(shù)、方法、字段、注解等信息,也能夠創(chuàng)建對象、調(diào)用方法等。
1.Class也是類,因此也繼承Obiect類
2.Class類對象不是new出來的,而是系統(tǒng)創(chuàng)建的
3.對于某個類的Class類對象,在內(nèi)存中只有一份,因為類只加載一次
4.每個類的實例都會記得自己是由哪個 Class 實例所生成
5.通過Class對象可以完整地得到一個類的完整結(jié)構(gòu),通過一系列API
6.Class對象是存放在堆的
7.類的字節(jié)碼二進制數(shù)據(jù),是放在方法區(qū)的,有的地方稱為類的元數(shù)據(jù)(包括 方法代碼變量名,方法名,訪問權(quán)限等等)
代碼演示:
package com.reflection.class_; /** * 對Class類特點的梳理 */ public class Class01 { public static void main(String[] args) throws ClassNotFoundException { //看看Class類圖 //1. Class也是類,因此也繼承Object類 //Class //2. Class類對象不是new出來的,而是系統(tǒng)創(chuàng)建的 //(1) 傳統(tǒng)new對象 /* 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對象 public Class<?> loadClass(String name) throws ClassNotFoundException { return loadClass(name, false); } */ Class cls1 = Class.forName("com.Cat"); //3. 對于某個類的Class類對象,在內(nèi)存中只有一份,因為類只加載一次 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ù)類的全限定名獲取對應(yīng)的類對象。
- newInstance():創(chuàng)建一個類的對象,要求該類必須具有默認的構(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類 對應(yīng)的 Class對象 //<?> 表示不確定的Java類型 Class<?> cls = Class.forName(classAllPath); //2. 輸出cls System.out.println(cls); //顯示cls對象, 是哪個類的Class對象 com.Car System.out.println(cls.getClass());//輸出cls運行類型 java.lang.Class //3. 得到包名 System.out.println(cls.getPackage().getName());//包名 //4. 得到全類名 System.out.println(cls.getName()); //5. 通過cls創(chuàng)建對象實例 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類對象
1.前提: 已知一個類的全類名,且該類在類路徑下,可通過Class類的靜態(tài)方法forName0獲取,可能拋出ClassNotFoundException,實例: Class cls1Class.forName("iava.lana.Cat”):
應(yīng)用場景:多用于配置文件,讀取類全路徑,加載類
2.前提:若已知具體的類,通過類的class 獲取,該方式 最為安全可靠,程序性能最高實例: Class cls2 = Catclass;
應(yīng)用場景:多用于參數(shù)傳遞,比如通過反射得到對應(yīng)構(gòu)造器對象
3.前提: 已知某個類的實例,調(diào)用該實例的getClass(方法獲取Class對象,實例Class clazz = 對象getClass0://運行類型
應(yīng)用場景: 通過創(chuàng)建好的對象,獲取Class對象
4.其他方式ClassLoader cl = 對象.getClass().getClassLoader();
Class clazz4=cl.loadClass("類的全類目");
5.基本數(shù)據(jù)(int, char,boolean,float,double,byte,long,short) 按如下方式得到Class類對象
6.基本數(shù)據(jù)類型對應(yīng)的包裝類,可以通過 .type 得到Class類對象
代碼演示:
package com.reflection.class_; import com.Car; /** * 演示得到Class對象的各種方式(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)用場景: 用于參數(shù)傳遞 Class cls2 = Car.class; System.out.println(cls2); //3. 對象.getClass(), 應(yīng)用場景,有對象實例 Car car = new Car(); Class cls3 = car.getClass(); System.out.println(cls3); //4. 通過類加載器【4種】來獲取到類的Class對象 //(1)先得到類加載器 car ClassLoader classLoader = car.getClass().getClassLoader(); //(2)通過類加載器得到Class對象 Class cls4 = classLoader.loadClass(classAllPath); System.out.println(cls4); //cls1 , cls2 , cls3 , cls4 其實是同一個對象 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類對象 Class<Integer> integerClass = int.class; Class<Character> characterClass = char.class; Class<Boolean> booleanClass = boolean.class; System.out.println(integerClass);//int //6. 基本數(shù)據(jù)類型對應(yīng)的包裝類,可以通過 .TYPE 得到Class類對象 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對象
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對象 */ 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的反射機制之獲取class詳解的文章就介紹到這了,更多相關(guān)Java的反射機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA如何獲取jvm和操作系統(tǒng)相關(guān)信息
這篇文章主要介紹了JAVA獲取jvm和操作系統(tǒng)相關(guān)信息,使用Java自帶的類進行獲取系統(tǒng)運行的相關(guān)信息,在這整理記錄分享一下,需要的朋友可以參考下2022-10-10Struts2源碼分析之ParametersInterceptor攔截器
這篇文章主要介紹了Struts2源碼分析之ParametersInterceptor攔截器,ParametersInterceptor攔截器其主要功能是把ActionContext中的請求參數(shù)設(shè)置到ValueStack中,,需要的朋友可以參考下2019-06-06使用Java將一個List運用遞歸轉(zhuǎn)成樹形結(jié)構(gòu)案例
這篇文章主要介紹了使用Java將一個List運用遞歸轉(zhuǎn)成樹形結(jié)構(gòu)案例,本文通過詳細的案例來解釋說明了如何去操作,需要的朋友可以參考下2021-06-06SpringBoot+MyBatis簡單數(shù)據(jù)訪問應(yīng)用的實例代碼
這篇文章主要介紹了SpringBoot+MyBatis簡單數(shù)據(jù)訪問應(yīng)用的實例代碼,需要的朋友可以參考下2017-05-05