Java学习笔记Day24:反射

反射:框架设计的灵魂

框架:半成品软件。可以在框架的基础上进行软件开发,简化编码
反射:将类的各个组成部分封装为其他对象,这就是反射机制
好处
1. 可以在程序运行过程中操作这些对象
2. 可以解耦,提高程序的可扩展性

Class对象功能
获取功能:
1. 获取成员变量

  • Field[] getFileds():获取所有public修饰的成员变量

  • Field getField(String name)获取指定名称的public修饰的成员变量

  • Field[] getDeclaredFields()获取所有成员变量,不考虑修饰符

  • Field getDeclaredFields(String name)

操作:

  • 设置值void set(Object obj,Object value)

  • 获取值get(Object obj)

  • 忽略访问权限修饰符的安全检查setAccessible(true):暴力反射

2.获取构造方法

  • Constructor<?>[] getConstructor()

  • Constructor getConstructor(类<?>…parameterTypers)

  • Constructor getDeclaredConstructor(类<?>…parameterTypers)

  • Constructor<?> getDeclaredConstructor()

操作:

  1. 创建对象:T newInstance(Object…initargs)

  2. 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法

Class personClass=Person.class;
Constructor constructor=personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象
Object person=constructor.newInstance("张三",23);
System.out.println(person);

3 .获取成员方法

  • Method[] getMethods()

  • Method getMethod(String name,类<?>…parameterTypers)

  • Method[] getDeclaredMethods()

  • Method getDeclaredMethods(String name,类<?>…parameterTypers)

操作:

  1. 执行方法:Object invoke(Object obj,Object…args)

  2. 获取方法名称:String getName

4.获取类名
String getName()

Java代码在计算机中经历的阶段:三个阶段
1. Source源代码阶段
2. Class类对象阶段
3. Runtime运行时阶段–》创建对象

获取Class对象的方式
1. 第一个阶段:Class.forName(“全类名”);(多用于配置文件,将类名定义在配置文件中。读取文件,加载类)
2. 第二个阶段:通过类名的属性class获取(多用于参数的传递 )
3. 第三个阶段:对象.getClass():getClass()方法在Object类中定义着(多用于对象的获取字节码方式)

//1.
Class cls1=Class.forName("cn.itcast.domain.Person");
System.out.println(cls1);
//2.
Class cls2=Person.class;
System.out.println(cls2);
//3.
Person p=new Person();
Class cls3=p.getClass();
System.out.println(cls3);

同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

案例:

需求:写一个“框架”,可以帮我们创建任意类的对象,并且执行其中任意方法

实现
1. 配置文件
2. 反射

步骤
1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
2. 在程序中加载读取配置文件
3. 使用反射技术来加载类文件进内存
4. 创建对象
5. 执行方法

//配置文件pro.properties
className=cn.itcast.domain.Student
methodName=sleep
public class ReflectTest {
    public static void main(String[] args) throws Exception{
        //1.加载配置文件
        //1.1创建Properties对象
        Properties pro=new Properties();
        //1.2加载配置文件,转换为一个集合
        //1.2.1获取class目录下的配置文件
        ClassLoader classLoader=ReflectTest.class.getClassLoader();
        InputStream is=classLoader.getResourceAsStream("pro.properties");
        pro.load(is);
        //2.获取配置文件中定义的数据
        String className=pro.getProperty("className");
        String methodName=pro.getProperty("methodName");
        //3.加载该类进内存
        Class cls=Class.forName(className);
        //4.创建对象
        Object obj=cls.newInstance();
        //5.获取方法对象
        Method m=cls.getMethod(methodName);
        //6.执行方法
        m.invoke(obj);
    }
}
发布了118 篇原创文章 · 获赞 12 · 访问量 2575

猜你喜欢

转载自blog.csdn.net/qq_42174669/article/details/104188133