快速开始
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下
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);