1、學習反射的時整理的筆記!Class類和ClassLoader類的簡單介紹
反射機制中的Class Class內部到底有什么呢?看下圖!
代碼:
Class cls=Person.class;1、Class類: 1、 對象照鏡子后可以得到的信息:某個類的數據成員名,方法和構造器、某個類到底實現了 哪些接口。對於每個類而言,JRE都為其保留一個不變的Class類型的對象。一個Class對象包 含可特定的某個類的有關信息。 2、Class對象只能由系統建立對象。 3、一個類在JVM中只會有一個Class實例。 4、每個類的實例都會記得自己是由哪個Class實例產生的。 5、Class本質上就是一個類!是一個用來描述指定類本身內部信息的一個類! 2、得到Class對象【三種方法】 1、直接通過: 類名.class Class cls=Person.class; 2、getClass()方式 Object obj=new Person(); Class cls2=obj.getClass(); 3、Class.forName("包名.類名")【最常用】【框架使用的最多】 try { Class cls3=Class.forName("cn.sgg.reflections.Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); } 3、反射中的泛型 舉例: Class<Person> cls3=(Class<Person>) Class.forName("cn.sgg.reflections.Person"); Class<?> cls3=(Class<Person>) Class.forName("cn.sgg.reflections.Person"); //?表示任意對象類型 4、Class類中的方法 1、創建類的實例的方法:newInstance() Class cls3=Class.forName("cn.sgg.reflections.Person"); Object obj=cls3.newInstance();//得到實例(通過:無參構造器) Object obj=cls3.newInstance(new Class[]{String.class,int.class});//得到實例(通過:有參構造器) 說明:一般來說,一個類若聲明了無參構造器,也要聲明一個有參構造器!(有參的是留給反射用的!) 2、Field<------>classType.getDeclaredFields(); 3、Method<----->getDeclaredMethod(getMethodName, new Class[]{}); 4、Constructor<------>getConstructor(new Class[]{int.class,String.class}); 5、反射的在哪里被使用? 框架中:
Servlet、Strust2等基礎框架中...... 6、類加載器:ClassLoader 說明: ClassLoader:類加載器是用來把類(class)裝進JVM的。JVM規范定義了兩種類型的類裝載器。 啟動類裝載器(bootstap) 用戶自定義裝載器(user-defined class loader)。 JVM在運行時會產生3個類加載器組成的初始化加載器層次結構, 如下圖:舉例: 1、//獲取一個系統類加載器 ClassLoader classLoader=ClassLoader.getSystemClassLoader(); System.out.println(classLoader); 2、//獲取一個系統類加載器 ClassLoader classLoader=ClassLoader.getSystemClassLoader(); System.out.println("系統加載器:"+classLoader); 3、//獲取系統類加載器的父類的加載器 ClassLoader parentLoader=classLoader.getParent(); System.out.println("系統加載器的父類加載器:"+classLoader); 4、//獲取擴展類加載器的父類加載器 classLoader=parentLoader.getParent(); System.out.println("擴展類加載器的父類加載器:"+classLoader); 5、//檢測當前類是由哪個類加載器加載的 try { ClassLoader classLoader2=Class.forName("cn.sgg.reflections.TestReflect").getClassLoader(); System.out.println(classLoader2); } catch (ClassNotFoundException e) { e.printStackTrace(); } 6、//檢測JDK 提供的Object類由哪個類加載器負責加載的 ClassLoader classLoader3; try { classLoader3 = Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader3); } catch (ClassNotFoundException e) { e.printStackTrace(); } 7、關於類加載器的一個重要方法: 系統類加載器可以加載本項目下的所有的對應的class文件和其他文件!/bin/xxx.文件后綴 舉例: //關於類加載器的一個重要方法: InputStream in=TestReflect.class.getResourceAsStream("xxxx.txt");
2、下面是測試代碼:
測試類1:
1 package cn.sgg.reflections; 2 3 /** 4 * 反射--被測試類: 5 * Created by Jason 2016-7-16 下午2:19:40 6 */ 7 public class Person { 8 String name; 9 private int age; 10 11 public Person(){} 12 public Person(String name){ 13 this.name=name; 14 } 15 public String getName() { 16 return name; 17 } 18 public void setName(String name) { 19 this.name = name; 20 } 21 public int getAge() { 22 return age; 23 } 24 public void setAge(int age) { 25 this.age = age; 26 } 27 }
測試類2:
1 package cn.sgg.reflections; 2 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.InputStream; 6 import java.lang.reflect.Field; 7 8 /** 9 * 反射-測試類: 10 * Created by Jason 2016-7-16 下午2:22:05 11 */ 12 public class TestReflect { 13 14 public static void main(String[] args) { 15 new TestReflect().testClassLoader(); 16 } 17 18 /** 19 * 測試反射的方法 20 */ 21 static void getProperty(){ 22 23 //1、得到Class對象 24 Class cls=Person.class; 25 26 Field[] fields=cls.getDeclaredFields(); 27 //2、得到Class對象 28 Object obj=new Person(); 29 Class cls2=obj.getClass(); 30 //3、得到Class對象 31 try { 32 Class<?> cls3=(Class<Person>) Class.forName("cn.sgg.reflections.Person"); 33 34 //獲得類實例 35 Object obj1=cls3.newInstance(); 36 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 } 41 42 43 static void testClassLoader(){ 44 45 //獲取一個系統類加載器 46 ClassLoader classLoader=ClassLoader.getSystemClassLoader(); 47 System.out.println("系統加載器:"+classLoader); 48 49 //獲取系統類加載器的父類的加載器 50 ClassLoader parentLoader=classLoader.getParent(); 51 System.out.println("系統加載器的父類加載器:"+classLoader); 52 53 //獲取擴展類加載器的父類加載器 54 classLoader=parentLoader.getParent(); 55 System.out.println("擴展類加載器的父類加載器:"+classLoader); 56 57 //檢測當前類是由哪個類加載器加載的 58 try { 59 ClassLoader classLoader2=Class.forName("cn.sgg.reflections.TestReflect").getClassLoader(); 60 System.out.println(classLoader2); 61 62 } catch (ClassNotFoundException e) { 63 e.printStackTrace(); 64 } 65 66 //檢測JDK 提供的Object類由哪個類加載器負責加載的 67 ClassLoader classLoader3; 68 try { 69 classLoader3 = Class.forName("java.lang.Object").getClassLoader(); 70 System.out.println(classLoader3); 71 } catch (ClassNotFoundException e) { 72 e.printStackTrace(); 73 } 74 75 //關於類加載器的一個重要方法: 76 InputStream in=null; 77 in=TestReflect.class.getResourceAsStream("xxxx.txt"); 78 } 79 }
測試結果:
系統加載器:sun.misc.Launcher$AppClassLoader@18d107f 系統加載器的父類加載器:sun.misc.Launcher$AppClassLoader@18d107f 擴展類加載器的父類加載器:null sun.misc.Launcher$AppClassLoader@18d107f null 得到圖片的劉對象:null