Q1:什么是反射?
反射:指在运行时,能取得任意类的内部信息,调用任意对象的属性及方法,的一种机制。
Q2:反射如何实现?
它借助于 Reflection API 实现,主要涉及四个类:
-
Field:提供类的属性信息;
- getFields() 、getDeclaredFields(),获取类公有或所有声明的字段;
- set() 设置属性值;
-
Method:提供类的方法信息;
- getMethods() 、getDeclaredMethods(),获取类公有或所有声明的非构造的方法;
- 之后使用 invoke() 调用该方法;
-
Constructor:提供类的构造方法信息;
- getConstructors() 、getDeclaredConstructors(),获取类公有或所有声明的构造方法;
-
Class:表示当前正运行类的实例;
Q3:反射机制中获得实例的方式有哪几种?
getClass和forName得到的Class实例是同一个实例还是不同的实例?
获取 Class 对象有三种方式:
- 通过对象的 getClass()
- 通过类的 class 属性
- Class.forName(“全限定名”)
三种方式获取的 Class 对象都是同一个,但前两种必须明确具体的类,不便扩展,推荐使用第三种,指定完整类名即可,更易扩展。
其中,如果反射获取的属性或方法是私有时,要使它可用,调用 setAccessible(true) 动态获取访问权限。
Q4:反射优缺点?
反射虽然提高了代码的灵活度,但它执行效率低,破环封装,能访问类的私有属性和方法,不安全。
Q5:哪里用到了反射?
常见应用:
-
JDBC:利用反射,加载数据库的驱动;
// 表示数据库的连接对象 Connection con = null; // 1、使用 CLASS 类加载驱动程序 Class.forName("com.mysql.jdbc.Driver"); //2、连接数据库 con = DriverManager.getConnection(连接地址,用户名,密码); // 3、关闭数据库 con.close();
-
工厂模式:利用反射,根据类的全限定名创建实例;
Class.forName("全限定名").newInstance();
-
Spring 中的 IoC,通过解析 XML 文件,获取 id 和 class 属性值,利用反射创建对应的实例,存入到 Spring 容器中。