反射是框架設(shè)計(jì)的靈魂
軟件框架:軟件本成品渡八,能夠幫助我們提高開發(fā)效率。Spring飘诗,SpringMVC居凶,Mybaties, Hadoop, Spark
反射的定義:講類的各個(gè)組成部分封裝為其他對(duì)象。這就是反射機(jī)制躯喇。
===========================================
Class字節(jié)碼對(duì)象
反射可以幫助我們創(chuàng)建對(duì)象
獲取類的字節(jié)碼對(duì)象辫封,有三種方式:
1.Source(源代碼階段):
Class.forName("全類名"); 將字節(jié)碼文件加載進(jìn)內(nèi)存,返回Class對(duì)象廉丽,多用于配置文件倦微,將類名定義在配置文件中,讀取文件正压,加載類
如:Class.forName("reflect.demo01.Animal");
2.Class階段:類名.class
通過類名的屬性class獲取欣福,多用于方法的參數(shù)的傳遞。
如 Animal.class
3.Runtime運(yùn)行時(shí)階段:對(duì)象名.getClass();
getClass()方法在Object類中定義著焦履,多用于對(duì)象的獲取字節(jié)碼的方式拓劝。
如:
Animal animal = new Animal();
animal.getClass();
package reflect.demo01;
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException {
/**
* 想執(zhí)行任何對(duì)象的任何方法
* 首先不知道對(duì)象,也不知道方法嘉裤,此時(shí)可以用反射
* 使用反射創(chuàng)建對(duì)象凿将,需要獲取字節(jié)碼,三個(gè)階段有不通的獲取方式
*
*/
Animal animal = new Animal(); //創(chuàng)建一個(gè)對(duì)象
//第一階段:源代碼階段
Class cls1 = Class.forName("reflect.demo01.Animal"); //用copy reference的方式价脾,需要拋出異常
//第二階段:Class階段
Class cls2 = Animal.class;
//第三階段:Runtime階段
Class cls3 = animal.getClass();
System.out.println(cls1 == cls2); //true
System.out.println(cls2 == cls3); //true
}
}
注意:
1.一個(gè)類對(duì)應(yīng)在內(nèi)存中對(duì)象的字節(jié)碼對(duì)象,有且只有一個(gè)笛匙,以上三種方式獲取的字節(jié)碼對(duì)象都是同一個(gè)對(duì)象侨把。
2.每個(gè)類都會(huì)有一個(gè)字節(jié)碼對(duì)象
成員方法:
1.獲取類的成員變量們
Field[] getFields() 獲取類中被public關(guān)鍵字修飾的成員變量
Field getField(String name)獲取類中指定名稱的被public關(guān)鍵字修飾的成員變量
Field[] getDeclareFields() 獲取類中所有成員變量(字段)犀变,不考慮權(quán)限修飾符
Field getDeclareField(String name) 獲取類中指定的成員變量
注意:凡是帶有Declared的方法獲取除了的字段,如果是被private修飾的字段秋柄,可以通過暴力放射設(shè)置為ture給其賦值
格式:nameField.setAccessible(true);
Field nameField = personClass.getDeclaredField("name");
//暴力反射获枝,能獲取私有變量的值
nameField.setAccessible(true);
Person p = new Person();
nameField.set(p, "迪麗熱巴");
System.out.println(p);
獲取字段的目的:
獲取值 field.get(對(duì)象)
設(shè)置值 field.set(對(duì)象,字段對(duì)應(yīng)的值)
2.獲取類的構(gòu)造方法們
Constructor<?>[] getConstructors():獲取類中所有被public修飾的構(gòu)造方法
Constructor<T>[] getConstructors(類<?>... parameterTypes):獲取指定的被public修飾的構(gòu)造方法
Constructor<?>[] getDeclaredConstructors()
Constructor<T>[] getDeclaredConstructors(類<?>... parameterTypes)
3.獲取類的成員方法們
Method[] getMethods():獲取類中所有被public修飾的成員方法
Method getMethod(String name, 類<?>... parameterTypes):獲取類中指定名稱的被public修飾的成員方法
Method[] getDeclaredMethods() 獲取私有的方法
Method getDeclaredMethod(String name, 類<?>... parameterTypes)
4.獲取類名
//獲取Person類的字節(jié)碼對(duì)象
Class personClass = Person.class;
//獲取全類名 reflect.demo02.Person
System.out.println(personClass.getName());
//只獲取類名 Person
System.out.println(personClass.getSimpleName());
package reflect.demo02;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 1.獲取類的成員方法們
* Field[] getFields() 獲取類中被public關(guān)鍵字修飾的成員變量
* Field getField(String name) 獲取類中指定名稱的被public關(guān)鍵字修飾的成員變量
*
* Field[] getDeclaredFields() 獲取類中所有成員變量(字段),不考慮權(quán)限修飾符
* Field getDeclaredField(String name) 獲取類中指定的成員變量
* 注意:凡是帶有Declared的方法獲取除了的字段骇笔,如果是被private修飾的字段省店,可以通過暴力放射設(shè)置為ture給其賦值
* 格式:Field nameField = personClass.getDeclaredField("name");
* //暴力反射,能獲取私有變量的值
* nameField.setAccessible(true);
* Person p = new Person();
*
* nameField.set(p, "迪麗熱巴");
* System.out.println(p);
*
* 獲取字段:
* 獲取值:field.get(對(duì)象)
* 設(shè)置值:field.set(對(duì)象,字段對(duì)應(yīng)的值)
*/
public class Demo01 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//獲取Person類的字節(jié)碼對(duì)象
Class personClass = Person.class;
//獲取全類名 reflect.demo02.Person
System.out.println(personClass.getName());
//只獲取類名 Person
System.out.println(personClass.getSimpleName());
}
/**
* 獲取類的成員方法們
* Method[] getMethods():獲取類中所有被public修飾的成員方法
* Method getMethod(String name, 類<?>... parameterTypes):獲取類中指定名稱的被public修飾的成員方法
*
* Method[] getDeclaredMethods() 獲取所有私有的方法笨触,用到暴力反射
* Method getDeclaredMethod(String name, 類<?>... parameterTypes) 獲取指定的私有方法
* 執(zhí)行方法:方法名.invoke(對(duì)象)
*
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static void getMethodsFromClass() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
//獲取Person類的字節(jié)碼對(duì)象
Class personClass = Person.class;
//獲取類中所有的被public修飾的成員方法
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
//獲取指定名稱的被public修飾的成員方法
Method m1 = personClass.getMethod("eat");
System.out.println(m1);
//獲取指定名稱帶參數(shù)的被public修飾的成員方法
Method m2 = personClass.getMethod("eat", String.class);
System.out.println(m2);
Person p = new Person();
//獲取一個(gè)無參數(shù)成員方法并執(zhí)行(執(zhí)行一個(gè)對(duì)象)
m1.invoke(p);
//獲取一個(gè)有參數(shù)的成員方法并執(zhí)行
m2.invoke(p, "飯飯");
//獲取私有的方法懦傍,并執(zhí)行
Method m3 = personClass.getDeclaredMethod("eat", int.class);
//通過暴力反射訪問私有方法
m3.setAccessible(true);
m3.invoke(p, 5);
}
/**
* 獲取類的成員變量們:
* Field[] getFields() 獲取類中被public關(guān)鍵字修飾的成員變量
* Field getField(String name)獲取類中指定名稱的被public關(guān)鍵字修飾的成員變量
*
* Field[] getDeclareFields() 獲取類中所有成員變量(字段),不考慮權(quán)限修飾符
* Field getDeclareField(String name) 獲取類中指定的成員變量
* 注意:凡是帶有Declared的方法獲取除了的字段芦劣,如果是被private修飾的字段粗俱,可以通過暴力放射設(shè)置為ture給其賦值
* @throws NoSuchFieldException
* @throws IllegalAccessException
*/
public static void getFieldsFromClass() throws NoSuchFieldException, IllegalAccessException {
//獲取Person類的字節(jié)碼對(duì)象
Class personClass = Person.class;
//通過Person類的字節(jié)碼對(duì)象的getFields()方法,獲取類中被public關(guān)鍵字修飾的成員變量:[nickName, tel]
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("==========");
//Field getField(String name) 獲取類中指定名稱的被public關(guān)鍵字修飾的成員變量
Field field = personClass.getField("nickName");
System.out.println(field);
Person p = new Person();
System.out.println(p);
//給p這個(gè)對(duì)象的nickName的值設(shè)置為老k
field.set(p, "老k");
System.out.println(p);
//獲取該字段的值
Object o = field.get(p);
System.out.println(o);
System.out.println("==========================");
// Field[] getDeclareFields() 獲取類中所有成員變量(字段)虚吟,不考慮權(quán)限修飾符
// Field getDeclareField(String name) 獲取類中指定的成員變量
Field[] fieldsDeclared = personClass.getDeclaredFields();
for (Field fieldDeclared : fields) {
System.out.println(fieldDeclared);
}
Field nameField = personClass.getDeclaredField("name");
//暴力反射寸认,能獲取私有變量的值
nameField.setAccessible(true);
nameField.set(p, "迪麗熱巴");
System.out.println(p);
}
/**
* 獲取類的構(gòu)造方法們
* Constructor<?>[] getConstructors():獲取類中所有被public修飾的構(gòu)造方法
* Constructor<T>[] getConstructors(類<?>... parameterTypes):獲取指定的被public修飾的構(gòu)造方法
*
* Constructor<?>[] getDeclaredConstructors() 獲取私有的構(gòu)造方法
* Constructor<T>[] getDeclaredConstructors(類<?>... parameterTypes)
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws InstantiationException
*/
public static void getConstructorsFromClass() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//獲取Person類的字節(jié)碼對(duì)象
Class personClass = Person.class;
//獲取Person類中的所有構(gòu)造方法
Constructor[] constructors = personClass.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//獲取指定的帶參數(shù)的構(gòu)造方法
Constructor ct1 = personClass.getConstructor(String.class, int.class);
System.out.println(ct1);
//創(chuàng)建一個(gè)對(duì)象,賦值并且強(qiáng)制類型轉(zhuǎn)換成Person對(duì)象
Person p2 = (Person)ct1.newInstance("xm", 12);
System.out.println(p2);
//獲取無參數(shù)的構(gòu)造方法,創(chuàng)建對(duì)象
Constructor ct2 = personClass.getConstructor();
//創(chuàng)建一個(gè)對(duì)象,并且強(qiáng)制類型轉(zhuǎn)換成Person對(duì)象
Person p1 = (Person)ct2.newInstance();
System.out.println(p1);
//獲取私有的構(gòu)造方法,通過暴力反射創(chuàng)建對(duì)象
Constructor declaredConstructor = personClass.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);
Person p3 = (Person)declaredConstructor.newInstance("xm");
System.out.println(p3);
System.out.println(declaredConstructor);
}
}