快速开始

1.什么是反射?

如果你研究过框架的底层原理或者咱们自己写过框架的话,一定对反射这个概念不陌生。

反射之所以被称为框架的灵魂,主要是因为它赋予了我们在运行时分析类以及执行类中方法的能力。

通过反射你可以获取任意一个类的所有属性和方法,你还可以调用这些方法和属性。

反射 (Reflection) 是 Java 的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。

2.反射机制优缺点

  • 优点 : 可以让咱们的代码更加灵活、为各种框架提供开箱即用的功能提供了便利
  • 缺点 :让我们在运行时有了分析操作类的能力,这同样也增加了安全问题。比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍差点,不过,对于框架来说实际是影响不大的

3.由一个例子引出反射

3.1需求

根据配置文件re. properties指定信息,创建Cat过象并调用方法say

re. properties文件

classfullpath=org.example.Cat
method=say

Cat

package org.example;

/**
 * @author aRu
 * @date 2021/5/3 10:01
 */
public class Cat {
    private String name = "招财猫";
    public int age= 3;

    public Cat() {
    }

    public Cat(String name) {
        this.name = name;
    }

    public void say(){
        System.out.println("miao~ i am "+name);
    }
}

工程目录如下,本次代码写在org.example.quickStart_01下

image-20210503213403742
3.2实现
package org.example.quickStart_01;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

/**问题的引入
 * @author aRu
 * @date 2021/5/3 10:04
 */
public class ReflectionQuickStart {
    public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //根据配置文件 创建Cat对象并调用 配置文件中指定的方法

        //1.读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\org\\example\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString();
        String method = properties.get("method").toString();
        System.out.println("类的全路径: "+classfullpath);
        System.out.println("方法名: "+method);

        //2.使用反射机制
        Class cls = Class.forName(classfullpath);
        //通过 cls 得到你加载的类 Cat的对象实例
        Object o = cls.newInstance();
        System.out.println("o的类型: "+o.getClass());
        //通过cls 得到你加载的类Cat的 method 方法
        Method method1 = cls.getMethod(method);
        //通过method1 调用方法: 即,通过方法对象 来实现调用方法
        method1.invoke(o);
        

    }
}


运行结果

类的全路径: org.example.Cat
方法名: say
o的类型: class org.example.Cat
miao~ i am 招财猫

补充

        //得到类的成员变量
        //注意: cls.getField("name")不能得到私有的属性
        Field nameField = cls.getField("age");
        System.out.println(nameField.get(o));

        //得到对象的构造函数
        Constructor constructor = cls.getConstructor();//()中可以指定构造参数类型,这里没写,则返回无参构造
        System.out.println("无参构造:"+constructor);

        Constructor constructor2 = cls.getConstructor(String.class);
        System.out.println("有参构造:"+constructor2);