反射是框架设计的灵魂。
什么是反射
反射是Java中的一种运行机制,与我们正常的代码思路完全不同,只有在运行时才会知道要操作的类是什么,能够完全访问类的属性和方法(包括private修饰的属性和方法)。
反射的使用方式
反射主要有四种使用方式,分别是知道类名直接根据类名className.class
获取Class对象、根据类路径Class.forName("classPath")
获取Class对象、根据对象实例通过getClass()
方法获取Class对象以及通过类加载器使用loadClass("classPath")
获取Class对象。
下面是反射四种方式的测试代码。
public class ReflectionDemo {
public static void main(String[] args) throws Exception {
//1.根据类名直接获得Class对象
Class clazz1 = Person.class;
System.out.println(clazz1.getName());
//newInstance()获取对象实例
Person person1 = (Person) clazz1.newInstance();
person1.setName("SKY");
System.out.println(person1.getName());
//2.根据类路径获得Class对象
//当前文件在com.sky.basis包下
Class clazz2 = Class.forName("com.sky.basis.Person");
System.out.println(clazz2.getName());
Person person2 = (Person) clazz2.newInstance();
//获取age属性
Field field = clazz2.getDeclaredField("age");
//设置属性值
field.setAccessible(true);
field.set(person2, 24);
System.out.println(person2.getAge());
//3.根据对象实例获得Class对象
Person person3 = new Person();
Class clazz3 = person3.getClass();
System.out.println(clazz3.getName());
Method method1 = clazz3.getDeclaredMethod("setName", String.class);
//调用公有方法
method1.invoke(person3, "sky");
System.out.println(person3.getName());
//4.根据类加载器获得Class对象
Class clazz4 = ClassLoader.getSystemClassLoader().loadClass("com.sky.basis.Person");
System.out.println(clazz4.getName());
Person person4 = (Person) clazz4.newInstance();
Method method2 = clazz4.getDeclaredMethod("setAge", int.class);
//调用私有方法
method2.setAccessible(true);
method2.invoke(person4, 28);
System.out.println(person4.getAge());
}
}
class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
private void setAge(int age) {
this.age = age;
}
}
反射的常见应用场景
我们在平时的开发过程中,直接接触到反射的机会比较少。如我们开篇所说,反射是框架设计的灵魂,一般在框架中使用反射的地方更多。我们平时在使用JDBC时,需要指定驱动,用到了反射的Class.forName("com.mysql.jdbc.Driver")
。Spring的IoC和AOP也是同样频繁使用了反射机制。
反射的缺点
由于反射能够直接操作private的字段和方法,造成了一定的安全隐患。另外由于反射动态解析Class,因此性能远远低于普通的Java代码。