【反射的优点】
1.增加程序的灵活性,避免将程序写死到代码里
2.代码简洁,提高代码的复用率,外部调用方便
3.对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
【反射的缺点】
【性能问题】
1.使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此Java反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
2.反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被 执行的代码或对性能要求很高的程序中使用反射。
3.使用反射会模糊程序内部逻辑
4.程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
【安全限制】
使用反射技术要求程序必须在一个没有安全限制的环境中运行。如果一个程序必须在有安全限制的环境中运行,如Applet,那么这就是个问题了
【内部暴露】
1.由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意料之外的副作用--代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
2.Java反射可以访问和修改私有成员变量,那封装成private还有意义么?
既然小偷可以访问和搬走私有成员家具,那封装成防盗门还有意义么?这是一样的道理,并且Java从应用层给我们提供了安全管理机制——安全管理器,每个Java应用都可以拥有自己的安全管理器,它会在运行阶段检查需要保护的资源的访问权限及其它规定的操作权限,保护系统免受恶意操作攻击,以达到系统的安全策略。所以其实反射在使用时,内部有安全控制,如果安全设置禁止了这些,那么反射机制就无法访问私有成员。
【反射是否真的会让你的程序性能降低?】
1.反射大概比直接调用慢50~100倍,但是需要你在执行100万遍的时候才会有所感觉
2.判断一个函数的性能,你需要把这个函数执行100万遍甚至1000万遍
3.如果你只是偶尔调用一下反射,请忘记反射带来的性能影响
4.如果你需要大量调用反射,请考虑缓存。
5.你的编程的思想才是限制你程序性能的最主要的因素
【代码案例】
定义一个实体类
package k3_fanshe;
/**
* @author nanzhi
* @date 2024/7/16 17:21
*/
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public void say() {
System.out.println("姓名:" + name +" "+ "年龄:" + age);
}
}
反射的测试类
package k3_fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author nanzhi
* @date 2024/7/16 17:27
*/
public class test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 获取Person类的Class对象
Class<Person> personClass = Person.class;
// 打印Person类的所有公共构造方法
System.out.println("personClass.getConstructors() = " + personClass.getConstructors());
// 获取Person类的构造方法,该构造方法接受一个String类型和一个Integer类型的参数
Constructor<Person> constructor = personClass.getConstructor(String.class, Integer.class);
// 使用获取到的构造方法创建一个新的Person对象,名为xh,年龄为18岁
Person xh = constructor.newInstance("小红", 18);
// 获取Person类的say方法
Method say = personClass.getDeclaredMethod("say");
// 调用xh对象的say方法
say.invoke(xh);
// 创建一个名为person的Person对象,名字为小旺,年龄为22岁
Person person = new Person("小旺", 22);
// 调用person对象的say方法
person.say();
}
}