java 基础------反射机制
一.反射的概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二.反射的工作原理
要想通过反射解剖一个类(比如创建该类的对象,访问该类的属性,调用该类的方法等等),可拆分为以下步骤操作:
- 得到该类对应的字节码对象,即类名.class对象
- 通过该类的字节码对象,调用相应的方法完成相应的目的
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 {
//通过文件路径得到字节码对象
Class<?> clazz = Class.forName("reflect.Student");
//字节码对象调用该方法产生类的对象实例
Student student = (Student)clazz.newInstance();
System.out.println(student);
/*-------------------------------------------------------------*/
//通过字节码对象得到该类的setId()方法
Method setIdMethod = clazz.getDeclaredMethod("setId", Integer.class);
//通过字节码对象得到该类的setName()方法
Method setNameMethod = clazz.getMethod("setName", String.class);
//执行得到的方法
setIdMethod.invoke(student, 20);
setNameMethod.invoke(student, "张三");
System.out.println(student);
/*-------------------------------------------------------------*/
//通过字节码对象得到该类的所有属性
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():可以是类的任何属性
- getFields():只能是公开属性
getDeclaredMethod()和getMethod()分别与此类似。
下面利用反射搞点事情。。。
在List<Integer>插入一个字符串值
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对象
Class<?> clazz = Class.forName("java.util.List");
//得到add方法
Method method = clazz.getMethod("add",Object.class);
//执行add该方法
method.invoke(list, "hahaha");
System.out.println(list);
}
}
image.png
原理分析:
- List<Integer>被编译后泛型会被替换,从实验中来看,应该是替换成了List<Object>;
- 而通过反射机制得到被编译后的add()方法,此时该方法的参数类型已经是Object了,然后就可以为所欲为了。。。
网友评论