JavaSE之反射机制
什么是反射
Java反射机制是指在运行状态中,对于任意一个类,都可以知道该类的所有方法和属性;对于任意一个对象,都可以调用该类的任何一个方法和属性;这种动态获取对象信息和动态调用对象的方法的功能称为Java的反射机制。
简单来说,就是在运行过程中,将对象的方法、属性等拆开成为多个对应对象,并且可以灵活调用获取的机制。
反射提供了哪些功能
- 运行时判断任意一个对象所属于的类
- 运行时构造任意一个类的对象
- 运行时判定任意一个类所具有的成员变量和对象
- 运行时调用任意一个对象的方法
- 动态代理
反射如何使用
反射最主要的类有以下类
java.lang.class; //类的抽象
java.lang.reflect.Constructor; //构造方法
java.lang.reflect.Field; //类的成员变量
java.lang.reflect.Method; //类的方法
java.lang.reflect.Modifier; //访问权限
获取Class对象的方式
为了表示方便,我构建了一个简单的JavaBean对象如下。
class JavaBean{
public String publicMsg;
private String privateMsg;
public JavaBean() {
System.out.println("无参构造器");
}
public void publicTest(){
System.out.println("公共测试方法");
}
private void privateTest(){
System.out.println("私有测试方法");
}
static {
System.out.println("动态加载");
}
}
现在来讲解一下获取Class对象的几种方式。
通过类的class属性
每一个类都会有一个Class静态属性,可以用其直接获取类对应的Class对象。
Class clazz=JavaBean.class;
通过Object对象的getClass方法
Object类中有一个getClass方法,便可以通过其获取Class对象。
JavaBean javaBean = new JavaBean();
Class clazz = javaBean.getClass();
通过Class类的forName()静态方法
这种方法是最为常用的,因为他与不用创建实际对象。
try {
Class clazz = Class.forName("reflect.JavaBean");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
通过ClassLoader构建Class
感觉这种方法是最为奇怪的,用的较少。
ClassLoader loader = JavaBean.class.getClassLoader();
try {
Class clazz = loader.loadClass("reflect.JavaBean");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
以上四种方法,除了最后一种外,其他的方法都会触发类中的static修饰的代码块,即加载其对象。
反射的使用
反射的最基础使用有
- 创建对象
- 调用方法
- 使用字段
创建对象
Class clazz=JavaBean.class;
Constructor<JavaBean> constructor=clazz.getConstructor();
try {
JavaBean javaBean = constructor.newInstance();
Method publicTest = clazz.getMethod("publicTest");
Method[] methods = clazz.getMethods();
for(Method method:methods){
System.out.println(method.getName());
}
Field[] fields = clazz.getFields();
for(Field field:fields){
System.out.println(field.getName());
}
publicTest.invoke(javaBean);
} catch (InstantiationException e) {
e.printStackTrace();
}
运行结果:
动态加载
无参构造器
publicTest
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
publicMsg
公共测试方法
Process finished with exit code 0
我们还需要注意,Class类的get方法中一般有两种,一种加了Declared,那么其是将private所修饰的也提取出来。
反射的优缺点
优点:
- 灵活创建代码,可以在运行时装配,无需在组件之间进行源代码的连接,更容易实现面向对象
- 可以通过配置文件来解耦合
缺点:
- 反射相当于是一条条指令去运行,耗费资源较大
- 反射可以忽略权限检查,可能会破坏封装性导致安全问题。
总结
我们正常写代码并不会用到反射,但是他是在很多框架中使用的很频繁,先讲述其基本概念,日后在做应用的博客。