反射: 框架设计的灵魂
框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
各个组成对象☞的是(成员变量,构造方法,成员方法)
好处:
1. 可以在程序运行过程中,操作这些对象。
2. 可以解耦,提高程序的可扩展性。
获取Class对象的方式:
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
多用于配置文件,将类名定义在配置文件中。读取文件,加载类 - 类名.class:通过类名的属性class获取
多用于参数的传递 - 对象.getClass():getClass()方法在Object类中定义着。
多用于对象的获取字节码的方式
结论:
同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class对象功能:
获取功能:
一. 获取成员变量
第一种:Field[] getFields() 获取所有public修饰的成员变量
第二种:Field getField(String name) 获取指定名称的 public修饰的成员变量
第三种:Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
第四种:Field getDeclaredField(String name) 获取指定名称的任何修饰的成员变量
操作:Field:成员变量
1. 设置值
修改成员变量值
void set(Object obj, Object value)
2. 获取值
get(Object obj)
3. 忽略访问权限修饰符的安全检查(private修饰的变量不允许直接访问的)
解决:setAccessible(true):暴力反射
不管你访问权限是什么,都能访问到你的成员变量。
二. 获取构造方法
Constructor<?>[] getConstructors()
Constructor getConstructor(类<?>… parameterTypes)
Constructor getDeclaredConstructor(类<?>… parameterTypes)
Constructor<?>[] getDeclaredConstructors()
Constructor:构造方法
创建对象:通过有参构造方法创建对象
T newInstance(Object… initargs)
如果使用空参数构造方法创建对象,
操作可以简化:Class对象的newInstance方法
三. 获取成员方法们:
Method[] getMethods()
Method getMethod(String name, 类<?>… parameterTypes)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, 类<?>… parameterTypes)
Method:方法对象
执行方法:
空参方法:
Object.invoke(Object obj, Object… args)
有参方法:
获取方法名称:
String getName:获取方法名
4. 获取全类名
String getName()
案例:
需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法
实现:
- 配置文件
- 反射
步骤:
- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建对象
- 执行方法
public class Reflect {
public static void main(String[] args) throws Exception {
//1.加载配置文件
//1.1创建properties对象
Properties pro=new Properties();
//1.2加载配置文件作为一个集合
//1.2.1获取class目录下的配置文件
ClassLoader classLoader=Reflect.class.getClassLoader();
InputStream is=classLoader.getSystemResourceAsStream("pro.properties");
pro.load(is);
//2.获取配置文件中的数据
String classname=pro.getProperty("className");
String methodname=pro.getProperty("methodName");
//3.加载该类进内存
Class cls= Class.forName(classname);
//4.创建对象
Object obj=cls.newInstance();
//5.获取方法
Method method=cls.getMethod(methodname);
//6.执行方法
method.invoke(obj);
}
}
反射机制以及作用
Java的反射机制是Java特性之一,反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对大家以后学习框架技术有很大的帮助。
那么什么是Java的反射呢?
大家都知道,要让Java程序能够运行,那么就得让Java类要被Java虚拟机加载。Java类如果不被Java虚拟机加载,是不能正常运行的。现在我们运行的所有的程序都是在编译期的时候就已经知道了你所需要的那个类的已经被加载了。 Java的反射机制是在编译并不确定是哪个类被加载了,而是在程序运行的时候才加载、探知、自审。使用在编译期并不知道的类。这样的特点就是反射。
那么Java反射有什么作用呢?
假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个程序员所写的类的时候,来完成自身代码的编译。
Java的反射机制它知道类的基本结构,这种对Java类结构探知的能力,我们称为Java类的“自审”。大家都用过Jcreator和eclipse。当我们构建出一个对象的时候,去调用该对象的方法和属性的时候。一按点,编译工具就会自动的把该对象能够使用的所有的方法和属性全部都列出来,供用户进行选择。这就是利用了Java反射的原理,是对我们创建对象的探知、自审。
Class类
要正确使用Java反射机制就得使用java.lang.Class这个类。它是Java反射机制的起源。当一个类被加载以后,Java虚拟机就会自动产生一个Class对象。通过这个Class对象我们就能获得加载到虚拟机当中这个Class对象对应的方法、成员以及构造方法的声明和定义等信息。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判定任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判定任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。