反射概述和功能介绍
反射的简介
反射的概念
反射,框架设计的灵魂,是将类中各个组成部分封装为其它对象,这就是反射机制。
反射的好处
- 可以在程序运行过程中操作这些对象。
- 解耦,来提高程序的可扩展性。
反射获取字节码Class对象的三种方法
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象。该方法多用于配置文件,将类名定义在配置文件中。读取文件,加载类。
- 类名.class:通过类名的属性类获取。 多用于参数的传递。
- 对象.getClass():getClass()方法在Object类中定义的,返回一个Class对象。故所有类都有这个方法。多用于对象获取字节码的方式。
- 注: 1. 同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个。2. 不同的字节码文件对应的class类对象均不相同。
Class对象获取功能概述
获取成员变量的方法
Field[] getFields():获取所有public修饰的成员变量。
Field[] getField(String name):获取指定名称的public修饰的成员变量。
Field[] getDeclaredFields():获取所有的成员变量,不受修饰符的影响。
Field getDeclaredFields(String name):获取指定名称的成员变量,不受修饰符的影响。
代码示例1
package Reflect.reflect;
import Reflect.domain.Person;
import java.lang.reflect.Field;
public class exmple01 {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class personClass = Person.class;
/*
- Field[] getFields():获取所有public修饰的成员变量。
- Field[] getField(String name):获取指定名称的public修饰的成员变量
*/
//2.获取Person里的成员变量
Field[] fields = personClass.getFields();
for (Field field : fields) {
//打印
System.out.println(field);
}
System.out.println("-------------------");
//3.获取Person中指定的成员变量
Field a = personClass.getField("a");
System.out.println(a);
System.out.println("-------------------");
//4. 获取成员变量中的值
Person p = new Person();
System.out.println( a.get(p));
System.out.println("-------------------");
//5. 设置成员变量中的值
a.set(p, "张三");
System.out.println(p);
System.out.println("=====================分隔线===================");
/*
- Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
- Field getDeclaredFields(String name):获取指定的成员变量,不考虑修饰符
*/
//获取所有的成员变量
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
System.out.println("-------------------");
//获取指定的成员变量
Field d = personClass.getDeclaredField("d");
d.setAccessible(true);//暴力反射
Object value = d.get(p);
System.out.println(value);
}
}
获取构造方法
(构造方法的特点:类名和方法名得相同,区别在于构造方法的参数不同)
Constructor<?>[] getConstructors()
Constructor< T > getConstructor(类<?>…parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor< T > getDeclaredConstructor(类<?>…parameterTypes)
注:其主要作用和获取成员变量的方法类似。
代码示例2
package Reflect.reflect;
import Reflect.domain.Person;
import java.lang.reflect.Constructor;
public class exmple02{
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class personClass = Person.class;
/*
Constructor<T> getConstructor(类<?>...parameterTypes)
*/
//有参构造
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
//创建对象
Object obj = constructor.newInstance("张三", 23);
System.out.println(obj);
System.out.println("---------------------------------------------");
//获取无参构造
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor);
//创建对象
Object obj1 = constructor1.newInstance();
System.out.println(obj1);
System.out.println("---------------------------------------------");
//在获取无参构造创建对象的时候,可以使用Class类中的newInstance()
Object o = personClass.newInstance();
System.out.println(o);
}
}
获取成员方法
Method[] getMethods()
Method getMethod(String name,类<?>… parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,类<?>… parameterTypes)
注:其主要作用和获取成员变量的方法类似。
代码示例3
package Reflect.reflect;
import Reflect.domain.Person;
import java.lang.reflect.Method;
public class exmple03{
public static void main(String[] args)throws Exception {
Class personClass = Person.class;
//获取指定名称的无参方法
Method eat_method = personClass.getMethod("eat");
Person p = new Person();
//执行方法
eat_method.invoke(p);
//获取指定名称的有参方法
Method eat_method2 = personClass.getMethod("eat", String.class);
eat_method2.invoke(p, "小鸡炖蘑菇");
//获取所以public修饰的方法
Method[] method = personClass.getMethods();
for (Method method1 : method) {
System.out.println(method1);
//获取所有方法名
System.out.println(method1.getName());
}
}
}
获取类名
String getName()
代码示例4
package Reflect.reflect;
import Reflect.domain.Person;
public class example05 {
public static void main(String[] args){
//获取class对象
Class personClass = Person.class;
//获取类名
String name = personClass.getName();
//打印
System.out.println(name);
}
}
注意事项
私有的不能直接被访问到值,访问的话会报错Exception in thread “main” java.lang.IllegalAccessException;故需要在访问时,忽略访问权限修饰符的安全检查,采用暴力反射的方式,具体如上代码示例1。
各个组成部分功能介绍
Field:成员变量
操作:
- 设置值:Object get(Object obj),需要传对象
- 获取值:set(Object obj, Object value)
Constructor:构造方法
作用:
- 创建对象:T newInstance(Object… initargs).
- 如果使用空参数构造方法创建对象,操作可以简化:使用Class对象中的newInstance().
Method :方法对象
作用:
- 执行方法:Object invoke()
- 获取方法名称:String getName()
结语
以上为本人自己在学习期间所做的笔记,若有错误欢迎大家指正!