1.類加載器:程序加載某個類時,若類不在內存中,就會通過加載連接初始化三部實現對類的初始化。
加載:將class文件讀入內存併爲之創建一個Class對象
鏈接:驗證內部結構,爲靜態成員分配內存,設置默認初始化值,將類的二進制數據符號引用替換爲直接引用
初始化:爲變量賦初值
2.類的加載時機:A:創建類的實例 B:訪問類的靜態變量或爲靜態變量賦值 C:調用類的靜態方法
D:使用反射方式強制創建類或接口的java.lang.Class對象 E:初始化某個類的子類
F:直接使用java.exe命令來運行某個主類
3.加載器分類:A:Bootstrap ClassLoader 根類加載器,負責java核心類的加載,在JDK中JRE的lib目錄下rt.jar文件中
B:Extension ClassLoader 擴展類加載器,負責JRE擴展類jre包的加載,在JDK中JRE的lib目錄下ext
目錄
C:Sysetm ClassLoader 系統類加載器,負責JVM啓動時來自java程序的Class文件
4.反射:通過字節碼文件去使用成員的過程該文件爲類名.class文件
獲取文件對象的方式:A:Object類的getClass()方法
B:數據類型的靜態class屬性
C:Class類的靜態方法forName()
package Reflect;
public class Demo1 {
public static void main(String[] args) throws Exception {
Person p1=new Person();
Class c1=p1.getClass();//Object類的getClass()方法
Class c2=Person.class;//數據類型的靜態class屬性
Class c3=Class.forName("Reflect.Person");//C:Class類的靜態方法forName()
System.out.println(c1.getName());//Reflect.Person
System.out.println(c2.getName());//Reflect.Person
System.out.println(c3.getName());//Reflect.Person
}
}
一般直接使用第二種最方便,但第三種可以把參數作爲配置文件的內容
5.反射的使用步驟:成員變量Field,構造方法 Constructor,成員方法 Method,用class字節碼文件對象得到對應的成
員對象,在通過該成員對象調用方法使用
6.通過反射獲取構造方法:
A:public Constructor[] getConstructors() 獲取公共的構造方法
ublic Constructor[] getDeclaredConstructors() 獲取所有的構造方法(包括私有)
B:public Constructor getConstructor(Class... parameterTypes) 根據構造參數獲取公共的指定構造
public Constructor getDeclaredConstructor(Class<?>... parameterTypes) 根據構造參數獲取指定構造(包括私
有,但是私有在使用的時候需要取消訪問限制)
public class Person {
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
exp:通過反射獲取構造方法並創建對象import java.lang.reflect.Constructor;
public class Demo2 {
public static void main(String[] args) throws Exception {
Constructor[] p=Person.class.getConstructors();
Constructor p2=Person.class.getDeclaredConstructor(String.class,int.class);
for (Constructor c : p) {
System.out.println(c);//獲取所有構造方法
}
p2.setAccessible(true);//取消訪問限制
Object obj=p2.newInstance("a",1);//利用反射創建對象
System.out.println(obj);
}
}
7.通過反射獲取成員變量並使用
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
/*
* public Field[] getFields()獲取公有的成員變量
public Field[] getDeclaredFields()獲取全部的成員變量,包括私有
public Field getDeclaredField(String name) 傳入變量名稱返回指定的成員變量對象,包括私有
public Field getField(String name)傳入變量名稱返回指定的成員變量對象,僅可獲取共有的
public void set(Object obj,Object value) 給一個對象的一個字段設置一個值
*/
public class Demo3 {
public static void main(String[] args) throws Exception {
Class c=Class.forName("Reflect.Person");
Constructor con=c.getDeclaredConstructor();
Object obj=con.newInstance();//通過反射創建對象
Field[] f=c.getDeclaredFields();//獲取全部變量(包括私有)
for (Field field : f) {//增強for遍歷獲取的變量
System.out.println(field);
}
Field f1=c.getDeclaredField("name");//反射獲取變量
Field f2=c.getDeclaredField("age");
f1.setAccessible(true);//取消檢測
f2.setAccessible(true);
f1.set(obj,"a");//通過反射給變量賦值
f2.set(obj, 1);
System.out.println(obj);
}
}
8.通過反射獲取成員方法並使用
/*public Method[] getMethods()獲取所有公共成員方法
public Method[] getDeclaredMethods()獲取所有成員方法,包括私有
public Method getMethod(String name, Class<?>... parameterTypes)參數一:方法名 參數二:方法參數類型.class 獲取指定的公共方法
public Method getDeclaredMethod(String name,Class<?>... parameterTypes)參數一:方法名 參數二:方法參數類型.class 獲取指定的方法,包括私有
Object invoke(Object obj, Object... args) 讓某一個對象使用這個方法,並且傳入參數
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Demo4 {
public static void main(String[] args) throws Exception {
Class c=Class.forName("Reflect.Person");
Constructor con=c.getConstructor();//反射創建對象
Object obj=con.newInstance();
Method [] m=c.getDeclaredMethods();//反射獲取成員方法
for (Method method : m) {
System.out.println(method);
}
Method m1=c.getDeclaredMethod("setName",String.class);//使用方法
Method m2=c.getDeclaredMethod("getName");
m1.invoke(obj, "a");
m2.invoke(obj);
System.out.println(obj);
}
}