day43-反射02

2.Class類2.1基本介紹

day43-反射02

文章插圖
  1. Class類也是類,因此也繼承Object類
    day43-反射02

    文章插圖
  2. Class類對象不是new出來的,而是系統創建的
  3. 對于某個類的Class類對象,在內存中只有一份,因為類只加載一次
  4. 每個類的實例都會記得自己是由哪個Class實例所生成
  5. 通過Class對象可以得到一個類的完整結構(通過一系列API)
  6. Class對象是存放在堆的
  7. 類的字節碼二進制數據,是放在方法區的,有的地方稱為類的元數據(包括 方法代碼,變量名,方法名,訪問權限等)
    當我們加載完類之后 , 除了會在堆里生成一個Class類對象,還會在方法區生成一個類的字節碼二進制數據(元數據)
例子:
package li.reflection.class_;import li.reflection.Cat;//對Class類的特點的梳理public class Class01 {public static void main(String[] args) throws ClassNotFoundException {//1.Class類對象不是new出來的,而是系統創建的//1.1.傳統的 new對象/**通過ClassLoader類中的loadClass方法:*public Class<?> loadClass(String name) throws ClassNotFoundException {*return loadClass(name, false);*}*///Cat cat = new Cat();//1.2反射的方式/**在這里debug,需要先將上面的Cat cat = new Cat();注釋掉 , 因為同一個類只加載一次,否則看不到loadClass方法* (這里也驗證了:3.對于某個類的Class類對象 , 在內存中只有一份,因為類只加載一次)* 仍然是通過 ClassLoader類的loadClass方法加載 Cat類的 Class對象*public Class<?> loadClass(String name) throws ClassNotFoundException {*return loadClass(name, false);*}*/Class cls1 = Class.forName("li.reflection.Cat");//2.對于某個類的Class類對象,在內存中只有一份 , 因為類只加載一次Class cls2 = Class.forName("li.reflection.Cat");//這里輸出的hashCode是相同的,說明cls1和cls2是同一個Class類對象System.out.println(cls1.hashCode());//1554874502System.out.println(cls2.hashCode());//1554874502}}【day43-反射02】Class類對象不是new出來的,而是系統創建的:
  1. Cat cat = new Cat();處打上斷點,點擊force step into , 可以看到

day43-反射02

文章插圖
  1. 注釋Cat cat = new Cat();,在Class cls1 = Class.forName("li.reflection.Cat");處打上斷點,可以看到 仍然是通過 ClassLoader類加載 Cat類的 Class對象

day43-反射02

文章插圖
2.2Class類常用方法public static Class<?> forName(String className)//傳入完整的“包.類”名稱實例化Class對象public Constructor[] getContructors() //得到一個類的全部的構造方法public Field[] getDeclaredFields()//得到本類中單獨定義的全部屬性public Field[] getFields()//得到本類繼承而來的全部屬性public Method[] getMethods()//得到一個類的全部方法public Method getMethod(String name,Class..parameterType)//返回一個Method對象,并設置一個方法中的所有參數類型public Class[] getInterfaces() //得到一個類中鎖實現的全部接口public String getName() //得到一個類完整的“包.類”名稱public Package getPackage() //得到一個類的包public Class getSuperclass() //得到一個類的父類public Object newInstance() //根據Class定義的類實例化對象public Class<?> getComponentType() //返回表示數組類型的Classpublic boolean isArray() //判斷此class是否是一個數組
應用實例
Car:
package li.reflection;public class Car {public String brand = "寶馬";public int price = 500000;public String color ="白色";@Overridepublic String toString() {return "Car{" +"brand='" + brand + '\'' +", price=" + price +", color='" + color + '\'' +'}';}}Class02:
package li.reflection.class_;import li.reflection.Car;import java.lang.reflect.Field;//演示Class類的常用方法public class Class02 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {String classAllPath = "li.reflection.Car";//1.獲取到 Car類 對應的 Class對象//<?>表示不確定的Java類型Class<?> cls = Class.forName(classAllPath);//2.輸出clsSystem.out.println(cls);//將會顯示cls對象是哪個類的Class對象class li.reflection.CarSystem.out.println(cls.getClass());//輸出cls的運行類型 class java.lang.Class//3.得到包名System.out.println(cls.getPackage().getName());//li.reflection :Class對象對應的類是在哪個包下面//4.得到全類的名稱System.out.println(cls.getName());//li.reflection.Car//5.通過cls創建一個對象實例Car car = (Car)cls.newInstance();System.out.println(car);//調用car.toString()//6.通過反射獲得屬性 如:brandField brand = cls.getField("brand");System.out.println(brand.get(car));//寶馬//7.通過反射給屬性設置值brand.set(car,"奔馳");System.out.println(brand.get(car));//奔馳//8.遍歷得到所有的屬性(字段)Field[] fields = cls.getFields();for (Field f:fields) {System.out.println(f.getName());//依次輸出各個屬性字段的名稱}}}

推薦閱讀