能够分析类能力的程序被成为反射(reflective)。
Java的反射机制主要提供了一下功能:
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时任意调用一个对象的方法;
- 在运行时改变fileds的内容;
0. 什么是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。
在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述,并能根据自身行为的状态和结构,调整或修改应用所描述行为的状态和相关的语意。
0.1 Java中的反射
Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。它使类和数据结构能够按名称动态检索相关信息,并允许在运行着的程序中操作这些信息。
但反射有两个缺点。第一个是性能问题,用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的。如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作中只耗用几毫秒。仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。
第二个缺点是安全,可以绕过java的基础安全机制(如“子类无法访问父类的私有属性或方法)
主要涉及的类
1. Class类
2. Constructor类
3. Field类
4. Method类
5. AccessibleObject类
示例
打印类信息
import java.util.*;
import java.lang.reflect.*;
public class ReflectionTest{
public static void main(String[] args){
ClassAnalyzer.printClass(Integer.class);
}
}
class ClassAnalyzer{
static public void printClass(Class cl){
System.out.print("class " + cl.getName());
// print super class info
Class superCl = cl.getSuperclass();
if (superCl != null && superCl != Object.class){
System.out.print(" extends " + superCl.getName());
}
// print interfaces info
Class[] interfaces = cl.getInterfaces();
for (int i = 0; i < interfaces.length; i++){
if (i == 0){
System.out.print(" implements ");
}
System.out.print(interfaces[i].getName() + " ");
}
System.out.print("{\n");
System.out.println("}");
}
static public void printConstructor(Class cl){
}
static public void printMethod(Class cl){
}
}
输出:
参考:Java反射教程