Java 反射(Reflect)详解

Java 反射(Reflect)详解

什么是反射?

反射是指Java程序可以检查自身的能力,并且在运行时获取和操作自身的类、接口、方法和属性等信息。Java反射提供了一种机制使得一个程序在运行期间可以获取自身的信息并且可以操作该类的内部属性、方法和构造方法。

反射的作用

反射主要有如下应用场景:

  • 动态创建对象或获取已有对象的信息;
  • 调用对象的方法;
  • 访问和修改类的成员变量等。

反射可以做很多的事情,例如动态创建对象、动态获取类的方法或属性信息、动态调用方法,还可以实现IOC容器、代理对象等功能。

反射相关概念

在了解反射之前,首先需要了解以下三个概念:

  • Class类:用于表示类或接口的实体,并提供了获取类或接口的变量、属性、方法和构造方法等信息的功能。
  • Field类:用于描述类或接口中的属性信息。
  • Method类:用于描述类或接口中的方法信息。

反射API的使用

获取Class类实例对象

Class<?> clazz = Class.forName("java.lang.String");

获取类的属性

Class<?> clazz = Class.forName("com.example.User");
Field[] fields = clazz.getDeclaredFields(); // 获取类中所有属性
for (Field field : fields) {
    System.out.println(field.getName()); // 输出属性名
}

获取类的方法

Class<?> clazz = Class.forName("com.example.User");
Method[] methods = clazz.getMethods(); // 获取类中所有方法
for (Method method : methods) {
    System.out.println(method.getName()); // 输出方法名
}

调用方法

Class<?> clazz = Class.forName("com.example.User");
Object obj = clazz.newInstance();
Method method = clazz.getDeclaredMethod("setName", String.class);
method.invoke(obj, "jack"); // 调用 setName 方法设置属性值

示例说明一:动态代理

动态代理是指在程序运行时生成代理类、代理对象,代替原有的类或对象,实现同样的接口或方法,并对委托的真实对象进行控制。在Java中,动态代理是基于反射实现的,即动态代理生成的类是基于原来类的实现,因此我们需要通过反射得到原来类的接口或方法信息。

// 定义接口
public interface UserService {
    String sayHello(String msg);
}

// 实现接口
public class UserServiceImpl implements UserService {
    @Override
    public String sayHello(String msg) {
        return "Hello " + msg + "!";
    }
}

// 生成代理类
public class UserServiceProxy implements InvocationHandler {
    private Object target;

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke method");
        Object result = method.invoke(target, args);
        System.out.println("after invoke method");
        return result;
    }
}

// 调用代理类的方法
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserServiceProxy proxy = new UserServiceProxy();
        UserService proxyService = (UserService) proxy.bind(userService);
        proxyService.sayHello("Jack");
    }
}

示例说明二:使用注解实现自定义ORM框架

ORM (Object Relational Mapping)框架是指通过反射实现Java对象与数据库表之间的映射。在Java程序中,可以使用注解定义与数据库表对应的实体类对象,并使用反射读取注解信息。同时,也可以使用Class类提供的一些方法获取实体类对象中的成员变量和成员方法,并使用数据库操作API实现数据库的CRUD操作。

// 定义注解
@Target(ElementType.FIELD) // 表示注解用在类的属性上
@Retention(RetentionPolicy.RUNTIME) // 表示注解在运行时保留
public @interface Column {
    String name() default ""; // 数据库字段名称
}

// 定义实体类
public class User {
    @Column(name = "id")
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private int age;
}

// 读取注解信息
public static String getColumnValue(Object obj, String columnName) throws Exception {
    Class<?> clazz = obj.getClass();
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        if (field.isAnnotationPresent(Column.class)) {
            Column column = field.getAnnotation(Column.class);
            if (column.name().equals(columnName)) {
                field.setAccessible(true);
                return String.valueOf(field.get(obj)); // 返回指定属性名的属性值
            }
        }
    }
    return null;
}

// 使用数据库操作API实现数据库的CRUD操作
public static void save(Object obj) throws Exception {
    Class<?> clazz = obj.getClass();
    StringBuilder sb = new StringBuilder();
    StringBuilder sbValue = new StringBuilder();
    sb.append("insert into ").append(clazz.getSimpleName()).append("(");
    sbValue.append(" values(");
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields) {
        if (field.isAnnotationPresent(Column.class)) {
            Column column = field.getAnnotation(Column.class);
            sb.append(column.name()).append(",");
            sbValue.append("'").append(getColumnValue(obj, column.name())).append("',");
        }
    }
    sb.deleteCharAt(sb.length() - 1).append(")");
    sbValue.deleteCharAt(sbValue.length() - 1).append(")");
    String sql = sb.toString() + sbValue.toString();
    // 执行数据库插入操作
    System.out.println(sql);
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 反射(Reflect)详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java 实战图书管理系统的实现流程

    Java 实战图书管理系统实现流程 本文将给出一个详细的Java 实战图书管理系统实现流程。我们将按照以下五步走进行: 1. 规划 首先我们需要规划我们的图书管理系统将包含哪些功能,这样我们才能更好的开始开发我们的应用程序。我们的规划包括以下几点: 实现基本的图书信息管理功能 包括添加、修改、删除、查询等功能 图书信息应该能方便地导出为Excel文件 实现图…

    Java 2023年5月24日
    00
  • mybatis开启spring事务代码解析

    在使用MyBatis操作数据库时,我们可以使用Spring事务管理器来管理事务。在本文中,我们将详细介绍如何在MyBatis中开启Spring事务,并提供两个示例说明。 1. 配置数据源 在使用MyBatis操作数据库时,我们需要配置数据源。下面是一个示例配置文件: <bean id="dataSource" class=&quot…

    Java 2023年5月18日
    00
  • struts2实现文件上传显示进度条效果

    下面是我为你准备的“Struts2实现文件上传显示进度条效果”的完整攻略,希望它对你有所帮助。此攻略分为以下三个部分: 基本原理 操作步骤 示例代码 1. 基本原理 Struts2本身并不支持实现文件上传的进度条效果,但是可以通过使用第三方插件和Ajax来实现。具体的实现原理如下: 在前端页面中使用Ajax发送文件上传请求 在后端使用Struts2实现文件的…

    Java 2023年5月20日
    00
  • 基于自定义校验注解(controller、method、(groups)分组的使用)

    基于自定义校验注解的使用可以提高代码的可读性和可维护性,可以定义自己的业务规则并在控制器中进行验证,从而更好地保障数据的安全性。下面给出一个完整的攻略,包括自定义注解的编写、控制器中的使用、注解的分组以及两个示例。 编写自定义注解 自定义注解应该使用@Target和@Retention注解对其进行标记,使其可以被正确地应用到需要校验的方法上。下面是一个简单的…

    Java 2023年5月20日
    00
  • java解析任意层数json字符串的方法

    关于“java解析任意层数json字符串的方法”的攻略,我会从以下几个方面进行讲解: JSON介绍 JSON解析器的选择 JSON解析实例 多层嵌套JSON解析实例 1. JSON介绍 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写。它基于JavaScript语法的子集,但在使用时可以被许多不同语言…

    Java 2023年5月26日
    00
  • Spring Boot整合Lombok的方法详解

    下面我将为您详细讲解“Spring Boot整合Lombok的方法详解”的完整攻略。 1. 什么是Lombok Lombok 是一个 Java 库,通过注解的形式,可以在编译期自动生成一些简单重复的代码,如 getter/setter/toString 等,减少代码的冗余,提高开发效率。 2. 引入Lombok依赖 在 pom.xml 文件中添加以下依赖: …

    Java 2023年5月19日
    00
  • JAVA图形界面(GUI)之表格的示例代码

    下面是详细讲解Java图形界面(GUI)之表格的示例代码的完整攻略: 1. 准备工作 在讲解示例代码之前,我们需要先进行一些准备工作。具体包括以下几步: 了解Java图形界面(GUI)相关的基础知识,包括Swing组件、布局管理器等等。 安装Java开发环境(JDK),这里以JDK 1.8为例。 确定开发工具。Java开发工具种类众多,推荐使用Eclipse…

    Java 2023年5月23日
    00
  • Java实现人脸识别登录、注册等功能(最新完整版)

    首先我们来介绍一下这篇文章。《Java实现人脸识别登录、注册等功能(最新完整版)》是一篇介绍如何使用Java语言实现人脸识别登录、注册等功能的文章。文章详细介绍了如何搭建环境、实现人脸注册、识别、显示等功能。下面将对文章中的内容进行详细讲解。 一、环境搭建 在文章中,作者先介绍了如何搭建Java开发环境,包括JDK、Eclipse、OpenCV等工具的安装和…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部