什么是反射
可以简单的理解为将类的各个组成部分封装为其他对象,这就是反射机制 比如ide(集成开发工具)里面的代码提示功能,判断某个包是否含有某个类,属性,变量等;或者你接手某个同事的代码时,可以用反射判断该同事某个方法是否写了的。
常用方法
得先知道用法,才能写代码
* 获取Class对象的方式:
1. Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
* 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
2. 类名.class:通过类名的属性class获取
* 多用于参数的传递
3. 对象.getClass():getClass()方法在Object类中定义着。
* 多用于对象的获取字节码的方式
* 注意:
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
* Class对象功能:
* 获取功能:
1. 获取成员变量们
* Field[] getFields() :获取所有public修饰的成员变量
* Field getField(String name) 获取指定名称的 public修饰的成员变量
* Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
* Field getDeclaredField(String name)
2. 获取构造方法们
* Constructor<?>[] getConstructors()
* Constructor<T> getConstructor(类<?>... parameterTypes)
* Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
* Constructor<?>[] getDeclaredConstructors()
3. 获取成员方法们:
* Method[] getMethods()
* Method getMethod(String name, 类<?>... parameterTypes)
* Method[] getDeclaredMethods()
* Method getDeclaredMethod(String name, 类<?>... parameterTypes)
4. 获取全类名
* String getName()
* Field:成员变量
* 操作:
1. 设置值
* void set(Object obj, Object value)
2. 获取值
* get(Object obj)
3. 忽略访问权限修饰符的安全检查
* setAccessible(true):暴力反射
* Constructor:构造方法
* 创建对象:
* T newInstance(Object... initargs)
* 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
* Method:方法对象
* 执行方法:
* Object invoke(Object obj, Object... args)
* 获取方法名称:
* String getName:获取方法名
方法的使用
先获取Class对象,再对调用该对象的变量,方法
先看下目录
获取Class对象
package model;
public class ReflectDemo1 {
public static void main(String[] args) throws Exception {
//获取Class对象
//根据全类名获取
Class user = Class.forName("model.User");
System.out.println(user);//class model.User
//类名的属性class获取
Class user2 = User.class;
System.out.println(user2);//class model.User
//根据对象获取
User user3 = new User();
Class user4 = user3.getClass();
System.out.println(user4);//class model.User
System.out.println(user == user2);//true
System.out.println(user == user4);//true
System.out.println(user2 == user4);//true
//用"=="表示 判断的是对象的内存地址,这里判断是不是同一个对象作用
}
}
获取变量
package model;
import java.lang.reflect.Field;
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
//获取成员变量
Class person = Person.class;
Person pObj = new Person();
//获取public成员变量
Field name = person.getField("name");
System.out.println(name);//public java.lang.String model.Person.name
name.set(pObj,"张三");
// System.out.println(pObj.getName()); 张三
System.out.println(name.get(pObj) );//张三
System.out.println("================");
Field[] fields = person.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("================");
//无视修饰符成员变量
Field card = person.getDeclaredField("card");
System.out.println(card);//private java.lang.String model.Person.card
card.setAccessible(true);//暴力反射
card.set(pObj,"身份证号码");
System.out.println(card.get(pObj));
System.out.println("================");
Field[] declaredFields = person.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
}
}
获取构造方法
这里用的是Person类做测试,先看下Person的代码
Person类的代码
package model;
public class Person {
public String name;
public Integer age;
private String card;
private String address;
public static void main(String[] args) {
String phone = "12345678901";
call(phone);
}
public Person(){
//System.out.println("无参构造被执行了");
}
public Person(String name,Integer age){
//System.out.println("name:"+name+",age:"+age);
}
public static void call(String phone) {
System.out.println("给"+phone+"打电话");
}
private static void info() {
System.out.println("这是个私有方法");
}
public String getCard() {
return card;
}
public void setCard(String card) {
this.card = card;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", card='" + card + '\'' +
", address='" + address + '\'' +
'}';
}
}
演示的代码
package model;
import java.lang.reflect.Constructor;
public class ReflectDemo3 {
public static void main(String[] args) throws Exception {
Class personClass = Person.class;
//获取无参构造方法
Constructor constructor = personClass.getConstructor();
System.out.println(constructor);
//实例化无参构造
Object o = constructor.newInstance();//Person o = new Person();
System.out.println(o);
System.out.println("=============");
//获取无参构造方法
Object o1 = personClass.newInstance();//Person o1 = new Person();
System.out.println(o1);
System.out.println("=============");
//获取所有构造方法
Constructor[] constructors = personClass.getConstructors();
for (Constructor constructor1 : constructors) {
System.out.println(constructor1);
}
System.out.println("=============");
//获取有参构造方法
Constructor constructor1 = personClass.getConstructor(String.class, Integer.class);
Object o2 = constructor1.newInstance("张三", 22);//Person o1 = new Person("张三", 22);
}
}
获取成员方法
package model;
import java.lang.reflect.Method;
public class ReflectDemo4 {
public static void main(String[] args) throws Exception{
Class<Person> personClass = Person.class;
Person p = new Person();
//获取所有public方法(包括继承的方法)
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("==========");
//获取所有员方法
Method[] declaredMethods = personClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
System.out.println("==========");
Method call = personClass.getMethod("call",String.class);//public static void model.Person.call(java.lang.String)
Object invoke = call.invoke(p,"12345678901");//call(""12345678901");
System.out.println("==========");
Method info = personClass.getDeclaredMethod("info");
info.setAccessible(true);//要想调用私有方法要暴力反射
info.invoke(p);
}
}