如何理解反射

如何理解反射

基础
关键问题

本文主要的目标是回答以下问题:

  1. 创建对象可以使用new,为什么我还需要反射?
  2. 如何使用反射创建未知类的对象?调用未知类的方法?
反射的定义

学习反射时,我们最不理解的一个问题就是,我要创建对象,直接使用new就可以了,为什么还需要反射?通过下面的定义,应该能够回答这个问题。

  1. 【核心定义】java反射机制就是对于任意一个未知的类,都能够创建其对象,调用其方法。
  2. 反射和new的区别:new只能针对编译阶段已经存在的类,如果在编译时这个类不存在,就无法创建对象,因为你都不知道该new谁。而使用反射,在编译阶段这个类不需要存在,只要在运行时要创建对象的时候存在即可。简单来说,new只能为已知的类创建对象,反射可以为未知的类创建对象。

上面的描述是一个比较通俗的说法,比较专业的说法是,new创建对象是静态编译,而反射创建对象是动态编译的过程。动态和静态分别代表的就是运行阶段和编译阶段。

反射的作用
  1. 反射的核心作用,就是能够为任意未知的类创建对象,换句话说,就是为别人的类创建对象。

什么情况下我会用到反射?

  1. 我要为一个类创建对象,但是我事先不知道这个类长什么样,可以使用反射。(IOC)
  2. 我要增强一个方法,但是我事先不知道这个方法长什么样,可以用反射。(AOP)
为什么说“反射是Java框架的基石”?
  1. 首先要理解框架的运行模式:框架是一套封装好的工具,然后用户基于框架开发,设计了各种类。这些类框架实现是不知道的,但是又必须将这些类实例化,并且调用其方法,最终发挥作用。
  2. 所以说,框架要解决的第一个问题就是:如何为别人写的类创建对象?而在上面的定义中可以发现,反射刚好就是解决这个问题的。因此,就有了“反射是java框架的基石”这一说法。
反射的常见用法
根据类名称创建对象

这个过程类似Spring中的@Autowired

/**
 * 1、首先根据类名称获取class对象
 * 2、然后实例化一个对象
 */
Class<Person> clazz = (Class<Person>) Class.forName("bean.Person");
Person person = clazz.newInstance();
调用类的构造方法
/**
 * 1、首先根据类名称获取class对象
 * 2、然后获取构造函数对象,指定参数类型
 * 3、调用构造函数对象的newInstance方法
 */
Class<Person> clazz = (Class<Person>) Class.forName("bean.Person");
Constructor<Person> constructor = clazz.getConstructor(String.class);
Person zhangsan = constructor.newInstance("zhangsan");
调用类的成员方法
/**
 * 1、首先根据类名称获取class对象
 * 2、然后获取成员方法对象,指定方法名称和参数类型列表
 * 3、调用成员方法,指定方法所属的对象,输入方法的参数
 */
Class<Person> clazz = (Class<Person>) Class.forName("bean.Person");
Method hello = clazz.getMethod("hello", String.class);
Person person = clazz.newInstance();
hello.invoke(person, "china");
操作成员变量
/**
 * 1、首先根据类名称获取class对象
 * 2、获取成员变量对象
 * 3、为成员变量赋值,指定所属的对象
 */
Class<Person> clazz = (Class<Person>) Class.forName("bean.Person");
Field name = clazz.getField("name");
Person person = clazz.newInstance();
name.set(person, "zhangsan");
总结
结论
  1. 通过反射的定义,现在基本理解了new和反射的区别,两者分别适用于不同的场景,通俗来讲,new的作用是实例化自己的类,而反射的作用是实例化任何人的类,主要用于实例化别人的类。
  2. 通过简单的示例代码,演示了反射的常见用法,对于一些特殊情况的用法,比如私有方法的调用,大同小异,就不进行详细描述了。

你可能感兴趣的:(Java,java,反射)