什么是反射?
简单的说:剖析java类中的各个组成部分,映射成一个个java对象。
在java.lang.reflect中。
反射用在哪?
多用于框架和组件,利用反射技术写出复用性高的通用程序
我只列出了反射中几个常用的API
类 Class
构造方法 Constructor
成员变量 Field
方法 Method
1.class 字节码文件
可以获得这个类的所有的特性
如何得到某个class类文件对应的class对象?
.已知类和对象的情况下:
类名.class
对象.getClass();
.未知类和对象的情况下:
Class.forName("包名.类名");
forName用于加载类字节码到内存中,并封装成一个Class对象
例:
// 获得一个.class 字节码文件 对应Class类对象
@Test
public void demo1() throws ClassNotFoundException {
// 已知类情况下 获得字节码对象
Class c1 = ClassTest.class;
// 已知一个对象,但是不知道这个对象属于哪个类,获得字节码对象
Object o = new ArrayList();
Class c2 = o.getClass(); // 等价于 ArrayList.class
// 未知类和对象情况下
String classDescription = "action.ClassTest";
Class c3 = Class.forName(classDescription);
}
2.Constructor
constructor类的实例对象代表类的一个构造方法
.得到某个类所有的构造方法
Constructor[] constructor = Class.forName("java.lang.String").getConstructor();
.得到制定的构造方法并调用
Constructor constructor = Class.forName("java.lang.String").getConstructor(String.class);
String str = (String)constructor.newInstance("abc");
Class类的newInstance()方法用来调用类的默认构造方法
String obj = (String)Class.forName("java.lang.String").newInstance();
例 :
// 调用指定构造方法
@Test
public void demo3() throws ClassNotFoundException, SecurityException,
NoSuchMethodException, IllegalArgumentException,
InstantiationException, IllegalAccessException,
InvocationTargetException {
// 已知类情况下,通过new 创建实例
ClassTest classTest = new ClassTest(10);
// 1. 获得字节码对象
Class c = Class.forName("action.ClassTest");
// 2. 获得指定构造方法
Constructor constructor = c.getConstructor(int.class);
// 3、调用构造方法 获得对象
Object o = constructor.newInstance(10);
}
3.Field
Field类代表某个类中的一个成员变量,并提供动态的访问权限
Field对象的获取:
.得到所有的成员变量
Field[] field = c.getField();// 取得所有Public属性
Field[] field = c.getDeclaredFields(); //取得所有声明的属性(包括私有)
.得到指定的成员变量
Field name =c.getField("name");
Field name =c.getDeclaredField("name");//私有
.设置Field变量是否可以访问
field.setAccessible(boolean);
.Field变量值的读取设置
field.get(obj);
field.set(obj,value);
例:
@Test
public void demo1() throws ClassNotFoundException, SecurityException,
NoSuchFieldException, InstantiationException,
IllegalAccessException {
// 以前方法操作变量
FieldMethodTest fieldMethodTest = new FieldMethodTest();
fieldMethodTest.num = 10;
// 1、获得字节码文件
Class c = Class.forName("cn.itcast.reflect.FieldMethodTest");
// 2、获得num成员变量 对应反射对象 Field
Field[] fields = c.getFields(); // 获得所有public属性
System.out.println(fields.length);
Field[] fields2 = c.getDeclaredFields();
System.out.println(fields2.length);
Field field = c.getDeclaredField("num");
// 3. 为num 赋值
Object o = c.newInstance(); // 调用默认构造方法
// 修改私有变量是 可见的
field.setAccessible(true);
field.set(o, 20);
System.out.println(field.get(o));
}
4. Method:
Method 和Field基本雷同 这里贴出例子
@Test
public void demo2() throws ClassNotFoundException, InstantiationException,
IllegalAccessException, SecurityException, NoSuchMethodException,
IllegalArgumentException, InvocationTargetException {
// 以前方式
FieldMethodTest fieldMethodTest = new FieldMethodTest();
fieldMethodTest.m("001");
// 1. 获得Class对象
Class c = Class.forName("action.FieldMethodTest");
// 2、获得对象
Object o = c.newInstance();
// 3. 获得m对象反射中Method对象
Method m = c.getMethod("m", String.class);
// 4. 调用o对象m方法
m.invoke(o, "008");
}