反射

在Java中的反射机制是指在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态创建/调用对象方法的功能称为Java语言的反射机制。

优点

可以在运行时动态的确定类型并创建实例,可以调用实例中的任意方法即是方法时private的。

缺点

  • 相比于编译时确定类型的方式,运行时确定类型创建实例会带来一定的性能消耗。
  • 反射需要运行时的权限,这种权限可能在安全管理器下运行时可能不存在。对于必须在受限的安全上下文(例如Applet)中运行的代码,这是一个重要的考虑因素。
  • 由于反射允许代码执行非反射代码中非法的操作(例如访问私有字段和方法),因此使用反射可能会导致意外的副作用,这可能会使代码无法正常工作并可能破坏可移植性。反射代码破坏了抽象,因此可能会随着平台的升级而改变行为。

FAQ

反射调用慢在哪里?

相对于在编译时确定对象类型,反射是在运行时动态创建对象并确定对象类型,所以会比编译时确定对象类型多一些性能消耗即慢。
例如

1
2
3
4
5
6
7
long start = System.currentTimeMillis();
for(int i=0; i<10000; i++)
{
User user = new User();
}
System.out.println(System.currentTimeMillis() - start);
// 耗时基本在4.5ms左右

1
2
3
4
5
6
7
8
long start = System.currentTimeMillis();
for(int i=0; i<10000; i++)
{
Class<?> clazz = Class.forName("com.zhongyp.advanced.refect.User", true, ReflectDemo.class.getClassLoader());
User user = (User) clazz.newInstance();
}
System.out.println(System.currentTimeMillis() - start);
// 耗时基本在20ms左右

参考资料

Java Reflection API