Java反射机制:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java的反射机制。
Java的反射机制的作用:是用来编写一些通用较高的代码或者框架的时候来使用。
反射的API:
- Class类
- Constructor类
- Field类
- Method类
Class类:
Java中java.lang.Class类用于表示一个类的字节码(.class)文件
如何得到某个.class文件对应的Class对象
已知类和对象的情况下:
- 类名.class;
- 对象.getClass();//Object类提供
未知类和对象的情况下:
- Class.forName("包名.类名");//forName方法用来加载类字节码到内存中,并封装成一个Class对象
//通过类名.class的方式
Class class1 = Person.class;
//通过对象.getClass()的方式
Person person = new Person();
Class class2 = person.getClass();
//Class类forName();获得(推荐)
Class class3 = Class.forName("com.imooc.javareflect.Person");
Field类:
某个类中的一个成员变量,并提供动态的访问权限
Field对象的获得:
- 得到所有的成员变量: Field[] fields= class.getFields();//取得所有public属性(包括了类继承)
- 获取所有声明的属性:Field[] fields=class.getDeclaredFields();
- 设置Field变量是否可以访问:field.setAccessible(boolean);
- 设置Field变量的值:field.set(obj,value);
- 得到指定的成员变量:
Field name=class.getFiled("name");
Field name=class.getDeclaredField("name");
@Test
//测试公有的属性
public void demo1() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
//获得Class
Class class1= Class.forName("com.imooc.javareflect.Person");
//获取属性
Field field = class1.getField("name");
//操作属性
Person p =new Person();
field.set(p,"Ally");
Object object = field.get(p);
System.out.println(object);
}
@Test
//测试私有的属性
public void demo2() throws Exception{
Class class2 = Class.forName("com.imooc.javareflect.Person");
//获取属性
Field field = class2.getDeclaredField("age");
//操作属性:
Person p =(Person) class2.newInstance();
field.setAccessible(true);
field.set(p,12);
Object object = field.get(p);
System.out.println(object);
}
Constructor类:
Constructor类的实例对象代表类的一个构造方法
得到某个类所有的构造方法:Constructor []constructors=Class.forName("").getConstructors();
得到指定的构造方法并调用:
Constructor constructor=Class.forName("java.lang.String").getConstructor(String.class);
String str=(String)constructor.newInstance("abc");
Class类中newInstance()方法是调用类的默认构造方法
Method类:
代表某个类中的一个成员方法
获取所有方法:
- getDeclaredMethods()
- getMethods()
获取指定的方法
- getDeclaredMethod(String name,Class<?>..parameterTypes)
- getMethod(String name,Class<?>..parameterTypes)
通过反射执行方法:
invoke(Object obj,Object ..args)
@Test
//测试公有的方法
public void demo1() throws Exception{
Class class1 = Class.forName("com.imooc.javareflect.Person");
Person person = (Person) class1.newInstance();
//获得公有的方法
Method method = class1.getMethod("eat");
//执行该方法
method.invoke(person);
}
@Test
//测试私有的方法
public void demo2() throws Exception{
Class class1 =Class.forName("com.imooc.javareflect.Person") ;
//实例化
Person person = (Person) class1.newInstance();
//获取方法
Method method = class1.getDeclaredMethod("run");
//设置私有的属性的访问权限
method.setAccessible(true);
method.invoke(person,null);
}
@Test
//测试带有参数的私有方法
public void demo3() throws Exception{
Class class1 = Class.forName("com.imooc.javareflect.Person");
Person person = (Person) class1.newInstance();
Method method = class1.getDeclaredMethod("sayHello", String.class);
method.setAccessible(true);
Object object = method.invoke(person,"Tom");
System.out.println(object);
}