1、简介
Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。即:在程序运行过程中分析类的一种能力(通过访问字节码.class文件,创建并使用对象的过程)
2、特点
- 对于任意一个类,都能够知道这个类的所有属性和方法
- 对于任意一个类,都能够调用它的任意一个属性和方法
3、功能
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法;
- 生成动态代理。
4、用法
获取类Class对象
1、类加载器:将类的字节码文件(.class)加载到内存中,并生成对应的Class对象。每个Class对象对应一个字节码文件。
2、作用
在运行时通过反射获取类的Class对象
3、获取类Class对象常用方法
- 根据对象获取:
Class clazz=对象名.getClass(); - 根据类名获取:
Class clazz=类名.class; - 根据类名字符串获取:
Class clazz.forName(“类的正名”); 正名:包类的路径名
类对象:
public class Person {
private String name;
public int age;
public int money;
public Person() {
}
public Person(String name, int age) {
System.out.println("有参构造器");
this.name = name;
this.age = age;
}
private Person(int age) {
this.age = age;
}
public void info(){
System.out.println("无参方法");
}
private void info(String name){
System.out.println("无参方法");
System.out.println("你的名字是:"+name);
}
public void info(int age){
System.out.println("有参方法");
System.out.println("今年年龄是:"+age);
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
获取Class对象:
public class ObjectText {
public static void main(String[] args) throws Exception {
//获取Class对象
//方法一
Class clazz1=Class.forName("cn.reflection.Person");
System.out.println(clazz1);
//方法二
Person person=new Person();
Class clazz2=person.getClass();
System.out.println(clazz2);
//方法三
Class clazz3=Person.class;
System.out.println(clazz3);
}
}
构造方法Constructor
1、作用
通过反射获取类的构造器
2、获取构造器对象
- getConstructor(Class<?>… parameterTypes)返回一个仅公共的构造方法
- getDeclaredContructor(Class<?>…parameterTypes) 返回一个私有的构造方法
- getConstructors()返回类所有的构造方法(不含私有)
3、常用方法
- String getName() 返回构造方法名
- T newInstance(Object…intargs) 使用此后构造方法创建并初始化对象(T向下转型)
public class ConstructorText {
public static void main(String[] args) throws Exception {
//1.获取对象
Class clazz=Class.forName("cn.reflection.Person");
//2.获取构造器
//无参构造
Constructor constructor1 = clazz.getConstructor();
String name1 = constructor1.getName();
System.out.println(name1);
//有参构造
Constructor constructor2 = clazz.getConstructor(String.class, int.class);
System.out.println(constructor2);
//私有的有参构造
Constructor constructor3 = clazz.getDeclaredConstructor(int.class);
System.out.println(constructor3);
//获取所有的所有的构造器,除私有的
Constructor[] constructor4 = clazz.getConstructors();
System.out.println(constructor4);
//3.创建初始化对象并输出,向下转型
Person person=(Person)constructor2.newInstance("zhangsan",22);
System.out.println(person);
}
}
成员方法Method
1、作用
通过反射获取类的成员方法
2、获取对象
- getMethod(String name,Class…parameterTypes)返回公共的成员方法
name:方法名;parameterTypes:方法的参数列表 - getDeclaredMethod(String,Class<?>)返回私有的成员方法
- getMethod()返回此类所有(不含私有)方法的数组
3、常用方法
- String getName() 返回方法名
- Object invoke(Object obj,Object…args)在指定对象上调用此方法,参数为args
- setAccessible(true);开启暴力反射,用于调用私有带参方法
public class MethodText {
public static void main(String[] args) throws Exception {
//1.创建反射对象的字节码文件
Class clazz=Class.forName("cn.reflection.Person");
//2.获取构造器,创建类的对象
Constructor constructor = clazz.getConstructor();
Object newInstance = constructor.newInstance();
//3.获取方法
//无参
Method method1 = clazz.getMethod("info");
System.out.println(method1.getName());
//私有有参
Method info = clazz.getDeclaredMethod("info", String.class);
System.out.println(info.getName());
//返回所有共有的方法,不包含私有
Method[] methods = clazz.getMethods();
System.out.println(methods);
for (Object obj:methods){
System.out.println(obj);
}
//4.调用私有方法并赋值
//开启暴力反射
info.setAccessible(true);
//调用此方法
Person invoke =(Person) info.invoke(newInstance, "小明");
//打印结果
System.out.println(invoke);
}
}
成员变量Field
1、作用
通过反射获取类的成员变量
2、获取对象
- getField(String name)返回一个公共的属性
- getDeclaredField(String name)返回一个私有属性
- getDeclaredFields()返回此类所有(含私有)属性的数组
3、常用方法
- void set(Object obj,Object value)设置obj对象的指定属性值
- setAccessible(true);开启暴力反射,用于调用私有带参方法
public class FieldText {
public static void main(String[] args) throws Exception {
//1.获取类的字节码文件
Class clazz = Class.forName("cn.reflection.Person");
//2.获取构造器,并创建对象
Constructor constructor = clazz.getDeclaredConstructor(int.class);
constructor.setAccessible(true);
Person ins = (Person) constructor.newInstance(12);
//3.获取变量
//共有变量
Field field1 = clazz.getField("age");
System.out.println(field1);
//私有变量
Field field2 = clazz.getDeclaredField("name");
System.out.println(field2);
//返回所有变量含私有
Field[] fields = clazz.getDeclaredFields();
System.out.println(fields);
for (Object obj : fields) {
System.out.println(obj);
}
//4.调用变量并赋值
field2.setAccessible(true);
field2.set(ins, "小明");
//打印对象
System.out.println(ins);
}
}