什么是反射?
反射就是框架设计的灵魂,这里解释的比较抽象哈,哈哈哈
那就有好多小伙伴问什么是框架了?
框架就是一个半成品软件,我们可以在框架的基础上进行软件开发,可以简化我们的程序代码,这篇文章我们是进行反射的讲解,这里就不做太多框架的解释了哈!
在讲解反射之前我们先说说反射对我们的好处吧!
1.我们可以在程序运行中去操作这些对象
2.可以解耦,提高程序的拓展性
获取Class对象的几种方式:
1.Class.forName("全类名") 包名+类名 (多用于配置文件,将类定义在配置文件中,读取文件,加载类)
2.类名.Class 通过类名直接创建Class对象 (多用于参数的传递)
3.对象.getclass() 通过对象调用getclass()方法 (多用于对象的获取字节码的方式)
注意:同一个字节码文件(.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个
Class对象的功能
1.获取成员变量们
Field[]getfields() 获取类中的所有public修饰的成员变量
Field getfield(string name) 获取类中指定名称的成员变量
Field[]getdeclarefields() 获取类中所有的成员变量
Field getdeclarefield(string name) 获取类中指定名称的成员变量
2.获取构造方法们
Constructor<?>[]getconstructors() 获取类中所有public修饰的构造函数
Constructor<T>getconstructor(构造函数参数类型 如:string string.class) 获取类中指定参数数据类型的构造函数
Constructor<?>[]getdeclareconstructors() 获取类中所有的构造函数
Constructor<T>getdeclareconstructor(构造函数参数类型 如:string string.class) 获取类中指定参数数据类型的构造函数
3.获取成员方法们
Method[]getmethods() 获取类中所有public修饰的成员方法
Method getmethod(string name,参数类型) 获取类中指定方法名和参数类型的成员方法
Method[]getdeclareMethods() 获取类中所有成员方法
Method getdeclareMethod(string name,参数类型) 获取类中指定方法名和参数类型的成员方法
4.获取类名
String getname() 获取类名
获取所有被public修饰的成员变量:
Class<Person> personClass = Person.class;
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
获取所有成员变量:
Class<Person> personClass = Person.class;
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
获取所有被public修饰的构造器:
Class<Person> personClass = Person.class;
Constructor<?>[] constructors = personClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
获取指定被public修饰的构造器,并创建对象:
Class<Person> personClass = Person.class;
Constructor<Person> constructor = personClass.getConstructor(String.class, int.class, double.class);
System.out.println(constructor);
Person p1 = constructor.newInstance("张三", 18, 193.9);
System.out.println(p1);
获取所有被public修饰的方法:
Class<Person> personClass = Person.class;
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
Field、Constructor、Method 操作方法
Field:
1.设置值:
void set(object obj,object value)
2.获取值:
get(object obj)
3.忽略访问权限修饰符的安全检查
setaccessible(true) 暴力反射
注意:当我们获取所有成员变量或者被private修饰的成员变量时,被private修饰的成员变量不能进行操作,必须对该成员变量进行暴力反射,才能操作该对象
Constructor:
1.创建对象:
T newinstance(构造函数的参数)
2.忽略访问权限修饰符的安全检查
setaccessible(true) 暴力反射
注意:当我们获取所有构造器或者被private修饰的构造器时,被private修饰的构造器不能进行操作,必须对该构造器进行暴力反射,才能操作该对象
Method
1.执行方法:
object invoke(object obj,参数[可选])
2.忽略访问权限修饰符的安全检查
setaccessible(true) 暴力反射
注意:当我们获取所有成员方法或者被private修饰的成员方法时,被private修饰的成员方法不能进行操作,必须对该成员方法进行暴力反射,才能操作该对象
这里演示一个小Demo,我们将类名和方法名写入到配置文中,通过反射动态调用方法,并去执行它
/*创建properties集合*/
Properties p=new Properties();
/*创建本类的class对象,获取class加载器*/
ClassLoader classLoader = Demo.class.getClassLoader();
/*通过加载器的...方法获取一个流对象*/
InputStream peizhi = classLoader.getResourceAsStream("peizhi");
/*将流对象作为参数加载到集合中*/
p.load(peizhi);
/*通过键获取值*/
String className = p.getProperty("className");
String methodName = p.getProperty("methodName");
/*创建配置文件中指定的全包名的类对象*/
Class<?> aClass = Class.forName(className);
Method method = aClass.getMethod(methodName);
method.invoke(aClass.getConstructor().newInstance());
这篇文章就到此结束啦!你是否明白了呢?