類在內存中的生命週期:加載-->使用-->卸載java
當程序主動使用某個類時,若是該類還未被加載到內存中,系統會經過加載、鏈接、初始化三個步驟來對該類進行初始化程序員
類的加載又分爲三個階段:數組
ui
就是指將類型的class字節碼數據讀入內存編碼
(2)鏈接:linkspa
①驗證:校驗合法性等code
②準備:準備對應的內存(方法區),建立Class對象,爲類變量賦默認值,爲靜態常量賦初始值。component
③解析:把字節碼中的符號引用替換爲對應的直接地址引用對象
(3)初始化:initialize(類初始化)即執行<clinit>類初始化方法,大多數狀況下,類的加載就完成了類的初始化,有些狀況下,會延遲類的初始化。blog
一、哪些操做會致使類的初始化?
(1)運行主方法所在的類,要先完成類初始化,再執行main方法
(2)第一次使用某個類型就是在new它的對象,此時這個類沒有初始化的話,先完成類初始化再作實例初始化
(3)調用某個類的靜態成員(類變量和類方法),此時這個類沒有初始化的話,先完成類初始化
(4)子類初始化時,發現它的父類尚未初始化的話,那麼先初始化父類
(5)經過反射操做某個類時,若是這個類沒有初始化,也會致使該類先初始化
二、哪些使用類的操做,可是不會致使類的初始化?
(1)使用某個類的靜態的常量(static final)
(3)用某個類型聲明數組並建立數組對象時,不會致使這個類初始化
(1)引導類加載器(Bootstrap Classloader)又稱爲根類加載器
它負責加載jre/rt.jar核心庫,它自己不是Java代碼實現的,也不是ClassLoader的子類,獲取它的對象時每每返回null
(2)擴展類加載器(Extension ClassLoader)
它負責加載jre/lib/ext擴展庫,它是ClassLoader的子類
它負責加載項目的classpath路徑下的類,它是ClassLoader的子類
(4)自定義類加載器
當你的程序須要加載「特定」目錄下的類,能夠自定義類加載器;
加載器的雙親委託模式
下一級的類加載器,若是接到任務時,會先搜索是否加載過,若是沒有,會先把任務往上傳,若是都沒有加載過,一直到根加載器,若是根加載器在它負責的路徑下沒有找到,會往回傳,若是一路回傳到最後一級都沒有找到,那麼會報ClassNotFoundException或NoClassDefError
類加載器之間不是繼承關係,是組合的方式實現的。
Java反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;
簡單理解爲JVM運行時會在方法區記錄全部class文件中全部類的信息(類名,屬性,方法),並將全部類又作爲Class類的對象。當調用某個類時就會將其先加載到內存中,
也就是將這個類做爲Class類的對象被建立出來。在Class類中定義了許多供操做(此類)的方法(建立對象,調用屬性和方法),從而能夠動態的修改程序結構
Class對象是反射的根源,全部Java類型均可以獲取它的類型對象。
Class
在方法區建立的,不是由程序員建立的,Class
沒有公共構造方法。
(1)類型名.class
要求編譯期間已知類型
獲取對象的運行時類型
(3)Class.forName(類型全名稱)
能夠獲取編譯期間未知的類型
(4)ClassLoader的類加載器對象.loadClass(類型全名稱)
能夠用系統類加載對象或自定義加載器對象加載指定路徑下的類型
能夠獲取:包、修飾符、類型名、父類(包括泛型父類)、父接口(包括泛型父接口)、成員(屬性、構造器、方法)、註解(類上的、方法上的、屬性上的)
public ClassLoader getClassLoader() | 【返回該類的類加載器】 |
public String toString() | 【將對象轉換爲字符串】 |
public Package getPackage() | 【獲取此類的包】 |
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 返回一個 Constructor 對象,該對象反映此 Class 對象所表示的類或接口的指定構造方法 |
public Constructor<?>[] getDeclaredConstructors() throws SecurityException | 【返回此 Class 對象表示的類聲明的全部構造方法】 |
public native int getModifiers(); | 【 返回此類或接口以整數編碼的 Java 語言修飾符,用二進制的某一位1,來表明一種修飾符】 |
public String getName() | 【以 String 的形式返回此 Class 對象所表示的實體(類、接口、數組類、基本類型或 void)名稱】 |
public native Class<? super T> getSuperclass(); | 【返回表示此 Class 所表示的實體(類、接口、基本類型或 void)的超類的 Class】 |
public Type getGenericSuperclass() | 【返回此 Class 所表示的實體(類、接口、基本類型或 void) 的直接超類的 Type】 |
public Class<?>[] getInterfaces() | 【肯定此對象所表示的類或接口實現的接口】 |
public Field getField(String name) | 【返回此 Class 對象所表示的類或接口的指定公共成員字段】 |
public Field[] getFields() throws SecurityException | 【返回此 Class 對象所表示的類或接口的全部可訪問公共字段】 |
public Field getDeclaredField(String name) | 【返回此 Class 對象所表示的類或接口的指定已聲明字段】 |
public Field[] getDeclaredFields() throws SecurityException | 【返回此 Class 對象所表示的類或接口所聲明的全部字段】 |
public Method getMethod(String name, Class<?>... parameterTypes) | 【返回此 Class 對象所表示的類或接口的指定公共成員方法】 |
public Method[] getMethods() throws SecurityException | 【返回此 Class 對象所表示的類或接口(包括那些由該類或接口 聲明的以及從超類和超接口繼承的那些的類或接口)的公共 member 方法】 |
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 【返回此 Class 對象所表示的類或接口的指定已聲明方法】 |
public Method[] getDeclaredMethods() throws SecurityException | 【此 Class 對象表示的類或接口聲明的全部方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法】 |
public T newInstance() | 【建立此 Class 對象所表示的類的一個新實例】 |
public Annotation[] getAnnotations() | 【返回此元素上存在的全部註釋】 |
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) | 【若是存在該元素的指定類型的註釋,則返回這些註釋,不然返回 null】 |
public T[] getEnumConstants() | 【若是此 Class 對象不表示枚舉類型,則返回枚舉類的元素或 null】 |
public boolean isMemberClass() | 【當且僅當底層類是成員類時返回 true】 |
public native boolean isInterface(); | 【斷定指定的 Class 對象是否表示一個接口類型】 |
一、直接經過Class對象來實例化(要求必須有無參構造)
(1)獲取該類型的Class對象
Class clazz = Class.forName("com.guigu.bean.User");
(2)獲取屬性對象
Field field = clazz.getDeclaredField("username");
(3)設置屬性可訪問
field.setAccessible(true);
(4)建立實例對象:若是操做的是非靜態屬性,須要建立實例對象
Object obj = clazz.newInstance();
(4)設置屬性值
field.set(obj,"chai");
若是操做靜態屬性變量,那麼實例對象能夠省略,用null表示
(1)獲取該類型的Class對象
Class clazz = Class.forName("com.atguigu.service.UserService");
(2)獲取方法對象
Method method = clazz.getDeclaredMethod("login",String.class,String.class);
(3)建立實例對象
Object obj = clazz.newInstance();
(4)調用方法
Object result = method.invoke(obj,"chai","123);
若是方法的權限修飾符修飾的範圍不可見,也能夠調用setAccessible(true)
若是方法是靜態方法,實例對象也能夠省略,用null代替
一、獲取子類的Class對象
二、調用getGenericSuperClass()獲取泛型父類
三、強轉爲ParameterizedType類型
獲取類上的註解:
一、獲取Class對象
二、調用getAnnotation()方法獲得註解對象
三、調用註解對象的配置參數的方法獲取配置參數值
獲取屬性上的註解:
一、獲取Class對象
二、獲取某個屬性Field對象
三、調用getAnnot ation()方法獲得註解對象
四、調用註解對象的配置參數的方法獲取配置參數值
獲取方法上的註解:
一、獲取Class對象
二、獲取某個方法method對象
三、調用getAnnot ation()方法獲得註解對象
public Class<?>[] getClasses():
【返回全部公共內部類和內部接口。包括從超類繼承的公共類和接口成員以及該類聲明的公共類和接口成員。】
public Class<?>[] getDeclaredClasses():
【返回 Class 對象的一個數組,這些對象反映聲明爲此 Class 對象所表示的類的成員的全部類和接口。包括該類所聲明的公共、保護、默認(包)訪問及私有類和接口,但不包括繼承的類和接口】
public Class<?> getDeclaringClass():
【若是此 Class 對象所表示的類或接口是一個內部類或內部接口,則返回它的外部類或外部接口,不然返回null。】
Array類提供了以下幾個方法:
public static Object newInstance(Class<?> componentType, int... dimensions):
【建立一個具備指定的組件類型和維度的新數組。】
public static void setXxx(Object array,int index,xxx value):
【將array數組中[index]元素的值修改成value。此處的Xxx對應8種基本數據類型,若是該屬性的類型是引用數據類型,則直接使用set(Object array,int index, Object value)方法。】
public static xxx getXxx(Object array,int index,xxx value):
【將array數組中[index]元素的值返回。此處的Xxx對應8種基本數據類型,若是該屬性的類型是引用數據類型,則直接使用get(Object array,int index)方法。】
String getName() | 返回此 Field 對象表示的字段的名稱 |
Object get(Object obj) | 返回指定對象上此 Field 表示的字段的值 |
int getModifiers() | 以整數形式返回由此 Field 對象表示的字段的 Java 語言修飾符 |
boolean equals(Object obj) | 將此 Field 與指定對象比較 |
Type getGenericType() | 返回一個 Type 對象,它表示此 Field 對象所表示字段的聲明類型 |
boolean getBoolean(Object obj) | 獲取一個靜態或實例 boolean 字段的值 |
int getInt(Object obj) | 獲取 int 類型或另外一個經過擴輾轉換能夠轉換爲 int 類型的基本類型的靜態或實例字段的值 |
void set(Object obj, Object value) | 將指定對象變量上此 Field 對象表示的字段設置爲指定的新值 |
void setShort(Object obj, short s) | 將字段的值設置爲指定對象上的一個 short 值 |
void setInt(Object obj, int i) | 將字段的值設置爲指定對象上的一個 int 值 |
boolean equals(Object obj) | 將此 Method 與指定對象進行比較 |
String getName() | 以 String 形式返回此 Method 對象表示的方法名稱 |
Object invoke(Object obj, Object... args) | 對帶有指定參數的指定對象調用由此 Method 對象表示的底層方法 |
Class<?> getReturnType() | 返回一個 Class 對象,該對象描述了此 Method 對象所表示的方法的正式返回類型 |
Class<?>[] getParameterTypes() | 按照聲明順序返回 Class 對象的數組,這些對象描述了此 Method 對象所表示的方法的形參類型 |
int getModifiers() | 以整數形式返回此 Method 對象所表示方法的 Java 語言修飾符 |
Type getGenericReturnType() | 返回表示由此 Method 對象所表示方法的正式返回類型的 Type 對象 |
Type[] getGenericParameterTypes() | 返回一個 Type對象的數組, Type以聲明順序表示由該對象表示的可執行文件的形式參數類型 |
Type[] getGenericExceptionTypes() | 返回一個 Type對象的數組, Type此可執行對象聲明拋出的異常 |
Class<?>[] getExceptionTypes() | 返回 Class 對象的數組,這些對象描述了聲明將此 Method 對象表示的底層方法拋出的異常類型 |
Class<?> getDeclaringClass() | 返回表示聲明由此 Method 對象表示的方法的類或接口的 Class 對象 |
Annotation[] getDeclaredAnnotations() | 返回直接存在於此元素上的全部註釋 |
boolean equals(Object obj) | 將此 Constructor 對象與指定的對象進行比較 |
String getName() | 以字符串形式返回此構造方法的名稱 |
Class<T> getDeclaringClass() | 返回 Class 對象,該對象表示聲明由此 Constructor 對象表示的構造方法的類 |
int getModifiers() | 以整數形式返回此 Constructor 對象所表示構造方法的 Java 語言修飾符 |
T newInstance(Object... initargs) | 使用此 Constructor 對象表示的構造方法來建立該構造方法的聲明類的新實例,並用指定的初始化參數初始化該實例 |
Class<?>[] getParameterTypes() | 按照聲明順序返回一組 Class 對象,這些對象表示此 Constructor 對象所表示構造方法的形參類型 |
Type[] getGenericParameterTypes() | 按照聲明順序返回一組 Type 對象,這些對象表示此 Constructor 對象所表示的方法的形參類型 |