——- android培训、java培训、期待与您交流! ———-
黑马程序员——反射
JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。动态获取类中信息,就是java反射。可以理解为对类的解剖。
- 反射的好处
- 大大提高了应用程序的扩展性
Class类
要想要对字节码文件进行解剖,必须要有字节码文件对象。
获取字节码文件对象三种方式:
Object类中的getClass()方法的。 想要用这种方式,必须要明确具体的类,并创建对象。
public static void getClassObject_1() { Person p = new Person(); Class clazz = p.getClass(); Person p1 = new Person(); Class clazz1 = p1.getClass(); System.out.println(clazz == clazz1); }
任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。 相对简单,但是还是要明确用到类中的静态成员。还是不够扩展。
public static void getClassObject_2() { Class clazz = Person.class; Class clazz1 = Person.class; System.out.println(clazz == clazz1); }
只要通过给定的类的 字符串名称就可以获取该类,更为扩展。 可是用Class类中的方法完成。该方法就是forName。 这种方式只要有名称即可,更为方便,扩展性更强。
public static void getClassObject_3() throws ClassNotFoundException { String className = "cn.itcast.bean.Person"; Class clazz = Class.forName(className); System.out.println(clazz); }
Constructor类
Constructor代表某个类的构造方法。
- 获取构造方法:
- 得到这个类的所有构造方法:
Constructor[] cons = Class.forName("cn.itheima.Person").getConstructors();
- 获取某一个构造方法:
Constructor con = Person.class.getConstructor(String.class, int.class);
- 得到这个类的所有构造方法:
- 创建实例对象:
Person p = (Person) con.newInstance("lisi", 30);
注:
- 创建实例时newInstance方法中的参数列表必须与获取Constructor的方法getConstructor方法中的参数列表一致。
- newInstance():构造出一个实例对象,每调用一次就构造一个对象。
- 利用Constructor类来创建类实例的好处是可以指定构造函数,而Class类只能利用无参构造函数创建类实例对象。
示例:
// 通过Constructor对象来创建类实例方法
public static void createPersonClass_2() throws Exception {
// 获取Person类的Class对象
String className = "cn.itheima.Person";
Class clazz = Class.forName(className);
// Class clazz=Person.class;
// 获取指定构造函数的类实例
Constructor con = clazz.getConstructor(String.class, int.class);
Person p = (Person) con.newInstance("lisi", 30);
System.out.println(p.toString());
}
Field类
Field类代表某个类中一个成员变量
方法
Field getField(String s);
// 只能获取公有和父类中公有Field getDeclaredField(String s);
// 获取该类中任意成员变量,包括私有setAccessible(ture);
// 如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。set(Object obj, Object value);
// 将指定对象变量上此Field对象表示的字段设置为指定的新值。Object get(Object obj);
// 返回指定对象上Field表示的字段的值。
示例:
package cn.itcast.reflect.demo;
import java.lang.reflect.Field;
public class ReflectDemo3 {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
getFieldDemo();
}
/*
* 获取字节码文件中的字段。
*/
public static void getFieldDemo() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Field field = null;// clazz.getField("age");//只能获取公有的,
field = clazz.getDeclaredField("age");// 只获取本类,但包含私有。
// 对私有字段的访问取消权限检查。暴力访问。
field.setAccessible(true);
Object obj = clazz.newInstance();
field.set(obj, 89);
Object o = field.get(obj);
System.out.println(o);
}
}
Method类
Method类代表某个类中的一个成员方法。
方法
Method[] getMethods();
// 只获取公共和父类中的方法。Method[] getDeclaredMethods();
// 获取本类中包含私有。Method getMethod("方法名", 参数.class(如果是空参可以写null));
Object invoke(Object obj, 参数);
// 调用方法。如果方法是静态,invoke方法中的对象参数可以为null。
示例:
package cn.itcast.reflect.demo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ReflectDemo4 {
public ReflectDemo4() {
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
getMethodDemo_3();
}
public static void getMethodDemo_3() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("paramMethod", String.class, int.class);
Object obj = clazz.newInstance();
method.invoke(obj, "小强", 89);
}
public static void getMethodDemo_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method method = clazz.getMethod("show", null);// 获取空参数一般方法。
// Object obj = clazz.newInstance();
Constructor constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("小明", 37);
method.invoke(obj, null);
}
/*
* 获取指定Class中的所有公共函数。
*/
public static void getMethodDemo() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
Method[] methods = clazz.getMethods();// 获取的都是公有的方法。
methods = clazz.getDeclaredMethods();// 只获取本类中所有方法,包含私有。
for (Method method : methods) {
System.out.println(method);
}
}
}