一 什么是反射
Java语言是一个严谨的编程语言,语言本身是静态的。为了能让语言具有动态编程的特性,必须要有反射机制。
正常情况下,如果已经有一个类,则肯定可以通过类创建对象.
而反射可以实现通过一个对象找到一个类.
二 Class类
Class类是java.lang包中的类.当程序使用某个类时,Java虚拟机会将该类加载到内存中,该类的class文件读入内存,并为该类创建一个java.lang.Class对象,它包含了与类有关的信息.每个类都有一个Class对象,即每当编写并编译了一个新类时,就会产生一个Class对象,被保存在同名的.class文件.在Java程序中获得Class对象通常有三种方式:
三 通过反射我们可以查看类的信息
可以借助java.lang.reflect包中的以下几个类实现:
Constructor —— 类中的构造方法
Field —— 类中的属性
Method —— 类中的方法
这三个类都是AccessibkeObject类的子类,他们和Class类共同完成类的反射操作.
下面就是一个使用Class类结合java.lang.reflect包中的类获得一个类完整结构的简单例子:
获取java.lang.Math类的声明(包含类的名称,方法,类的继承关系),类的父类及实现的接口
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) {
Class > c1 = null;
try {
//这里用Class的forName()方法获得想要的类
c1 = Class.forName("java.lang.Math");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取实现的全部接口
Class> c[] = c1.getInterfaces();
//打印所有接口
for (int i = 0; i < c.length; i ++) {
System.out.println("c[i] = " + c[i]);
}
//获取全部的构造方法
Constructor> con[] = c1.getConstructors();
for (int i = 0; i < con.length; i ++) {
System.out.println("c[i] = " + con[i]);
}
//获取全部的方法
Method m[] = c1.getMethods();
for (int i = 0; i < m.length; i ++) {
Class> r = m[i].getReturnType();
Class> p[] = m[i].getParameterTypes();
int xsf = m[i].getModifiers();
System.out.println(Modifier.toString(xsf) + " ");
System.out.println(r.getName() + " ");
System.out.println(m[i].getName() + " ");
System.out.println("(");
for (int j = 0; j < p.length; j ++) {
System.out.println(p[j].getName() + " " + "arg" + j);
if (j < p.length - 1) System.out.println(",");
}
}
//获取父类名
Class > c2 = c1.getSuperclass();
System.out.println("父类名为: " + c2.getName());
}
}
这个例子讲解的不错:https://www.cnblogs.com/fzz9/p/7738381.html
四 反射安全吗?
反射被广泛地用于那些需要在运行时检测或修改程序行为的程序中。这是一个相对高级的特性,只有那些语言基础非常扎实的开发者才应该使用它。如果能把这句警示时刻放在心里,那么反射机制就会成为一项强大的技术,可以让应用程序做一些几乎不可能做到的事情。
五 反射的缺点 Drawbacks of Reflection
尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。在我们使用反射技术时,下面几条内容应该牢记于心:
性能第一
反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。
安全限制
使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了。
内部暴露
由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化