小米面试官:说说Java的反射

383 阅读2分钟

反射是框架设计的灵魂。

什么是反射

反射是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代码

欢迎关注微信公众号:SKY技术修炼指南