27. Java中的反射机制
2024-10-28 00:00:01  阅读数 985

1、Java中创建对象的方式

  • new + 构造方法
  • 反序列化(存储在文件中对象,还原回来)
  • java反射机制

2、已经使用反射的场景

  • jdbc
    • 加载驱动 Class.forName("com.mysql.jdbc.Driver");
  • servlet
    • servlet 对象有服务器创建
    • <servlet-class>com.company.project.servlet.LoginServlet</servlet-class>
  • mybatis
    • 将查询结果封装到 指定类型的对象中,mybatis 来创建对象
    • <select id ="findById" resultType="com.company.project.po.User">

3、Java 反射的概念

在运行过程中,可以动态根据类的地址来获取类的信息(构造方法,成员方法,成员变量),以及动态根据类的信息来创建对象,来调用对象的方法、属性的功能成为反射机制。

Java 反射的作用:

动态获取类的信息,进一步实现需要的功能。

Java 反射的API:

  • Class 用于获取类的属性、方法等信息

  • Constructor 构造方法

  • Method 方法

  • Field 成员变量

4、Java 中Class 对象

使用反射机制来操作,首先我们需要在运行时获取类的Class对象。

Class对象中包含类的信息(一个类的Class对象只有一个,与字节码文件对应)。

获取Class的三种方式:

(1)通过Object中的getClass()

(2)通过类的class属性

(3)通过Class类的forName静态方法以获取该类对应的Class对象,这是最安全的,性能也是最好的。

package com.company.project.Reflect;

public class ClassDemo {
    public static void main(String[] args) {
        /*
         *  使用反射机制来操作,首先我们需要在运行时获取类的Class对象
         *  Class对象中包含类的信息(一个类的Class对象只有一个,与字节码文件对应)
         */
        //获取Class的三种方法
        //(1)通过Object中的getClass()
        User user1 = new User();
        User user2 = new User();
        
        Class c1 = user1.getClass();
        Class c2 = user2.getClass();
        System.out.println(c1 == c2);       //true
        
        //(2)通过类的class属性
        Class c3 = User.class;
        System.out.println(c1 == c3);       //true
        
        //(3)通过类的地址(常用的)
        try {
            Class c4 = Class.forName("com.company.project.Reflect.User");
            System.out.println(c1 == c4);   //true
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }   
    }
}

5、Java 中Field对象

package com.company.project.Reflect;

import java.lang.reflect.Field;

public class FieldDemo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
        //指定类的路径
        String className = "com.company.project.Reflect.User";
                
        //获取包含对象信息的Class对象
        Class c = Class.forName(className);
                
        //通过Class获取User对象
        Object obj = c.newInstance();
        
        //获取属性
        Field numf = c.getDeclaredField("num");
        //设置私有权限
        numf.setAccessible(true);
        //给属性赋值
        numf.setInt(obj, 10);
        
        //获取所有的属性
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            System.out.println(field.getName());
            String name = field.getName();
            String getname = "get" + String.valueOf(name.charAt(0)).toUpperCase()+name.substring(1);
            System.out.println(getname);
        }
    }
}

6、java中的method

package com.company.project.Reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MethodDemo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        //指定类的路径
        String className = "com.company.project.Reflect.User";
        
        //获取包含对象信息的Class对象
        Class c = Class.forName(className);
        
        //通过Class获取User对象
        Object obj = c.newInstance();
        
        //获取指定方法
        Method m = c.getDeclaredMethod("eat", String.class);
        //设置私有权限
        m.setAccessible(true);
        //调用私有方法
        m.invoke(obj, "cat");
        
        //获取所有的方法
        Method[] methods = c.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
    }
}