java 基礎(chǔ)------反射機(jī)制
一.反射的概述
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中注祖,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法询一;對(duì)于任意一個(gè)對(duì)象隐孽,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制健蕊。
二.反射的工作原理
要想通過(guò)反射解剖一個(gè)類(lèi)(比如創(chuàng)建該類(lèi)的對(duì)象菱阵,訪(fǎng)問(wèn)該類(lèi)的屬性,調(diào)用該類(lèi)的方法等等)绊诲,可拆分為以下步驟操作:
- 得到該類(lèi)對(duì)應(yīng)的字節(jié)碼對(duì)象送粱,即類(lèi)名.class對(duì)象
- 通過(guò)該類(lèi)的字節(jié)碼對(duì)象,調(diào)用相應(yīng)的方法完成相應(yīng)的目的
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo1 {
/**
* @throws Exception
*
*/
public static void main(String[] args) throws Exception {
//通過(guò)文件路徑得到字節(jié)碼對(duì)象
Class<?> clazz = Class.forName("reflect.Student");
//字節(jié)碼對(duì)象調(diào)用該方法產(chǎn)生類(lèi)的對(duì)象實(shí)例
Student student = (Student)clazz.newInstance();
System.out.println(student);
/*-------------------------------------------------------------*/
//通過(guò)字節(jié)碼對(duì)象得到該類(lèi)的setId()方法
Method setIdMethod = clazz.getDeclaredMethod("setId", Integer.class);
//通過(guò)字節(jié)碼對(duì)象得到該類(lèi)的setName()方法
Method setNameMethod = clazz.getMethod("setName", String.class);
//執(zhí)行得到的方法
setIdMethod.invoke(student, 20);
setNameMethod.invoke(student, "張三");
System.out.println(student);
/*-------------------------------------------------------------*/
//通過(guò)字節(jié)碼對(duì)象得到該類(lèi)的所有屬性
Field[] field = clazz.getDeclaredFields();
for (Field field2 : field) {
System.out.println(field2);
}
}
}
class Student{
private int id;
private String name;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int id,String name){
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return "["+this.id+","+this.name+"]";
}
}
ps:里面兩組方法注意一下
- getDeclaredFields():可以是類(lèi)的任何屬性
- getFields():只能是公開(kāi)屬性
getDeclaredMethod()和getMethod()分別與此類(lèi)似掂之。
下面利用反射搞點(diǎn)事情抗俄。。世舰。
在List<Integer>插入一個(gè)字符串值
package reflect;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Demo1 {
/**
* @throws Exception
*
*/
public static void main(String[] args) throws Exception {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(30);
//得到List.class對(duì)象
Class<?> clazz = Class.forName("java.util.List");
//得到add方法
Method method = clazz.getMethod("add",Object.class);
//執(zhí)行add該方法
method.invoke(list, "hahaha");
System.out.println(list);
}
}
原理分析:
- List<Integer>被編譯后泛型會(huì)被替換动雹,從實(shí)驗(yàn)中來(lái)看,應(yīng)該是替換成了List<Object>跟压;
- 而通過(guò)反射機(jī)制得到被編譯后的add()方法胰蝠,此時(shí)該方法的參數(shù)類(lèi)型已經(jīng)是Object了,然后就可以為所欲為了震蒋。茸塞。。