前言
很早就看过了反射,但是很久没用着一块的知识怕给忘了,但是着一块又很重要,就干脆重新回顾一下反射加深以下印象好了。反射经常是结合注解和泛型一起,通常用来写框架,平时开发中除非特殊情况不然很少用到,但这并不是不好好掌握这些内容的理由,要往上进阶,这些基础的内容就必须掌握好。
反射能做什么
那么有些问题:反射能做什么?学过反射但很少用到反射原因是什么呢?
反射可以在运行时动态的修改class文件的内容,众所周知,java在编译完成后会生成.class文件,反射是在运行时能够获取任意类的属性方法并可以为字段赋值调用方法,不论是什么访问权限的。
其实有时候点进一些框架的源码就会发现,有很多的反射泛型等内容,我现在用的少的原因,总结了一些,就是菜。
获取Class类的几种方式
在java中,常用的获取Class类对象有以下3种方式:
1. Class.forName("com.ph.control.Person")
通过这种传入全包名的方式调用Class的forName方法获取Class对象
2. Person.class
通过这种直接调用类名.class获取该类的Class对象。
3. new Person().getClass();
通过任意对象的getClass方法获取Class对象。
反射获取类中的字段并改变其值
对于一个已经存在的对象,可以通过反射获取到其任意字段的内容并给其字段赋值:
package com.ph.control;
/**
* Created by panhao on 17-6-21.
*/
public class Person {
private String name;
private int age;
private String telNum;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getTelNum() {
return telNum;
}
public void setTelNum(String telNum) {
this.telNum = telNum;
}
private void showMsg(){
System.out.println("展現消息------");
}
}
Class<Person> personClass = Person.class;
Person person = personClass.newInstance();
//反射改变字段
person.setAge(20);
System.out.println(person.getAge());
Field field = personClass.getDeclaredField("age");
field.setAccessible(true);//去掉访问权限
field.set(person, 222);
System.out.println(person.getAge());
在控制台打印输出可以看到:通过反射成功的为person对象的age属性赋值,因为age是private类型的,所以要调用的field的setAccessible(true)来去掉访问权限的限制
反射获取方法并调用该方法
可以通过反射得到一个类的实例对象并通过反射获取到它的所有权限的方法,并调用invoke方法执行它:
Class<?> clazz = Class.forName("com.ph.control.Person");
//反射执行方法
Class<Person> personClass = Person.class;
Person person = personClass.newInstance();
Method showMsg = personClass.getDeclaredMethod("showMsg");
showMsg.setAccessible(true);
showMsg.invoke(person);
在控制台的打印可以看到,通过反射调用了该方法