Java的反射机制是在运行状态中,对于任意一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能叫做Java的反射机制。反射其实就是加载类,并获取类的各个组成部分。
加载类:
java中有一个Class类用于代表某一个类的字节码。获取class对象的方式有三种:① 调用Class类的forName(),② 通过 类名.class; ③ 对象.getClass();
反射类的组成部分的方法有:
① 获取public类型的各个组成部分:
getConstructor(Class...parameterTypes);
getMethod(String name,Class...parameterTypes);
getField(String name);
② 获取private类型的各个组成部分:
getDeclaredConstructor(Class...parameterTypes);
getDeclaredMethod(String name,Class...parameterTypes);
getDeclaredField(String name);
从类中获取各个组成部分是为了使用该类的各个部分。
使用反射机制,调用Person类中的构造函数,示例代码:
Person:
public class Person {
public Person()
{
System.out.println("Person ");
}
public Person(String name)
{
System.out.println("Person的姓名为:"+name);
}
public Person(String name,int age)
{
System.out.println("Person的姓名为:"+name+",年龄为"+age);
}
private Person(int age)
{
System.out.println("private age"+age);
}
}
Demo:
public class Demo {
// 反射无参数的构造函数
@Test
public void test1() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(null);
Person p = (Person) c.newInstance(null);
}
// 反射带一个参数的构造函数
@Test
public void test2() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class);
Person p = (Person) c.newInstance("zhangsan");
}
// 反射两个参数的构造函数
@Test
public void test3() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getConstructor(String.class, int.class);
Person p = (Person) c.newInstance("lisi", 20);
}
// 反射private的构造函数
@Test
public void test4() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Constructor c = clazz.getDeclaredConstructor(int.class);
// private修饰的只能在类内部调用,但是反射可以通过下面方式调用private修饰的。
c.setAccessible(true);// 暴力反射
Person p = (Person) c.newInstance(15);
}
// 反射无参数构造函数的另一种方式,等效于test1
@Test
public void test5() throws Exception {
Class clazz = Class.forName("cn.itcast.reflect.Person");
Person p = (Person) clazz.newInstance();// 该方法只能调用无参数的构造方法;
}
}
以上代码都是通过junit.Test来测试。运行结果如下:
Person
Person的姓名为:zhangsan
Person的姓名为:lisi,年龄为20
private age15
Person
利用反射机制中的Method执行方法是public Object invoke(Object object,Object... args),其中第一个参数为对象(当反射的是static类型的方法是,对象可以是null),第二个参数为方法所需要的参数。注意:在jdk 1.4时,没有可变参数,通过数组给参数列表传入参数,所以在反射main方法时,在传入参数列表时,① 把传入的数组类型强制转化成Object类型 ② 把传入的数组类型嵌套到Object数组中;