Java | 注解和反射的介绍及结合使用

关注:CodingTechWork

Java注解和反射的使用与实践

  在Java编程中,注解(Annotation)和反射(Reflection)是两个强大的功能,它们广泛应用于框架开发、配置管理、代码分析等领域。虽然这两个概念在初学者看来可能有些晦涩难懂,但它们的应用却能极大地提升代码的灵活性和可维护性。本文将介绍注解和反射的基本原理与使用,并通过代码示例展示它们如何应用于实践。

注解(Annotation)的介绍与原理

注解的概念

  注解是一种特殊的标记,它可以添加在类、方法、变量等地方,供编译器或运行时工具使用。Java中的注解并不会直接影响程序的逻辑,它们本身只是一些元数据。然而,通过注解,开发者可以给代码添加额外的信息或提供某些特定功能的控制,常见的用途包括:

  • 代码生成:在编译时自动生成代码或文档。
  • 配置管理:通过注解来管理配置,替代传统的XML配置文件。
  • 框架控制:许多框架(如Spring、Hibernate)都依赖于注解来简化开发,减少冗余代码。

注解的定义与使用

  注解的定义使用@interface关键字,常见的注解包括@Override@Deprecated@SuppressWarnings等。

自定义注解示例

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 定义一个自定义注解
@Target(ElementType.METHOD)  // 该注解仅可应用于方法
@Retention(RetentionPolicy.RUNTIME)  // 注解在运行时可访问
public @interface MyAnnotation {
    String value() default "default";  // 注解的属性
}
public class MyClass {
    @MyAnnotation(value = "Hello World")  // 使用自定义注解
    public void myMethod() {
        System.out.println("This is my method!");
    }
}

注解的访问

可以通过反射机制访问注解,获取注解的信息。使用Class类的getMethod()方法获取方法信息,再通过getAnnotations()获取方法上的注解。

import java.lang.reflect.Method;

public class AnnotationDemo {
    public static void main(String[] args) throws Exception {
        Class<MyClass> clazz = MyClass.class;
        Method method = clazz.getMethod("myMethod");

        if (method.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
            System.out.println("Annotation value: " + annotation.value());
        }
    }
}

注解的应用

  在Java开发中,注解广泛应用于很多领域。例如,Spring框架中使用注解来实现依赖注入、事务管理等功能。通过注解,开发者可以更加简洁地进行配置,减少XML文件的繁琐。

反射(Reflection)的介绍与原理

反射的概念

  反射是指程序在运行时动态地获取类的信息(如类的构造方法、字段、方法等),并能够调用这些方法或修改这些字段。反射机制使得Java程序能够在运行时“自我检查”,进而实现一些动态功能,如动态代理、框架设计等。

反射的基本操作

  反射的基本操作是通过Class类来进行的。Class类提供了获取类信息的方法,如获取类的构造方法、字段、方法等。

获取类的信息

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void display() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}
public class ReflectionDemo {
    public static void main(String[] args) throws Exception {
        // 通过反射获取Class对象
        Class<?> clazz = Class.forName("Person");

        // 获取构造方法并创建实例
        Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
        Object person = constructor.newInstance("John", 30);

        // 获取方法并调用
        Method method = clazz.getMethod("display");
        method.invoke(person);
    }
}

反射修改字段的值

import java.lang.reflect.Field;

public class ReflectionModifyField {
    public static void main(String[] args) throws Exception {
        Person person = new Person("Alice", 25);
        
        // 获取Person类的name字段
        Field field = Person.class.getDeclaredField("name");
        field.setAccessible(true);  // 设置可访问私有字段
        field.set(person, "Bob");  // 修改字段值
        
        // 调用display方法输出修改后的结果
        person.display();  // 输出:Name: Bob, Age: 25
    }
}

反射的应用

  反射机制常常与注解一起使用,尤其在框架中。比如Spring框架利用反射来实现依赖注入,Hibernate框架利用反射来进行对象关系映射(ORM)。

注解与反射的结合应用

  在实际开发中,注解和反射常常是结合使用的。一个典型的应用场景是在框架中使用注解来标记某些方法或类,然后通过反射来动态地处理这些标记。

自定义注解和反射结合的应用

  假设我们有一个简单的场景,需要根据方法上的注解来决定是否执行该方法:

import java.lang.annotation.*;
import java.lang.reflect.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Execute {
    boolean value() default true;
}

public class MyService {
    
    @Execute(value = true)
    public void task1() {
        System.out.println("Task 1 executed");
    }

    @Execute(value = false)
    public void task2() {
        System.out.println("Task 2 executed");
    }
}
public class AnnotationReflectionDemo {
    public static void main(String[] args) throws Exception {
        MyService service = new MyService();
        Method[] methods = MyService.class.getDeclaredMethods();

        for (Method method : methods) {
            if (method.isAnnotationPresent(Execute.class)) {
                Execute executeAnnotation = method.getAnnotation(Execute.class);
                if (executeAnnotation.value()) {
                    method.invoke(service);  // 执行方法
                }
            }
        }
    }
}

结果分析

  在上述代码中,我们定义了一个Execute注解,表示是否需要执行某个方法。通过反射,我们遍历MyService类中的所有方法,判断方法上是否存在@Execute注解,如果注解的value属性为true,则执行该方法。

总结

  注解和反射是Java中非常强大的特性,它们为开发者提供了动态编程的能力。注解主要用于为代码添加元数据,而反射则允许程序在运行时检查和操作对象。二者结合使用,可以实现许多灵活的功能,例如动态代理、依赖注入、自动化配置等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948755.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动态库dll与静态库lib编程4:MFC规则DLL讲解

文章目录 前言一、说明二、具体实现2.1新建项目2.2 模块切换的演示 总结 前言 动态库dll与静态库lib编程4&#xff1a;MFC规则DLL讲解。 一、说明 1.前面介绍的均为Win32DLL&#xff0c;即不使用MFC的DLL。 2.MFC规则DLL的特点&#xff1a;DLL内部可以使用MFC类库、可以被其他…

对比学习损失函数 - InfoNCE

InfoNCE Loss &#xff1a;构建高效对比学习模型 引言 对比学习中的InfoNCE损失函数是自监督学习领域的重要进展&#xff0c;它通过最大化正样本对之间的相似度并最小化负样本对的相似度&#xff0c;有效地引导模型学习到数据的本质特征。InfoNCE不仅提高了表示学习的质量&am…

家用万兆网络实践:紧凑型家用服务器静音化改造(二)

大家好&#xff0c;这篇文章我们继续分享家里网络设备的万兆升级和静音改造经验&#xff0c;希望对有类似需求的朋友有所帮助。 写在前面 在上一篇《家用网络升级实践&#xff1a;低成本实现局部万兆&#xff08;一&#xff09;》中&#xff0c;我们留下了一些待解决的问题。…

【STC库函数】Compare比较器的使用

如果我们需要比较两个点的电压&#xff0c;当A点高于B点的时候我们做一个操作&#xff0c;当B点高于A点的时候做另一个操作。 我们除了加一个运放或者比较器&#xff0c;还可以直接使用STC内部的一个比较器。 正极输入端可以是P37、P50、P51&#xff0c;或者从ADC的十六个通道…

东京大学联合Adobe提出基于指令的图像编辑模型InstructMove,可通过观察视频中的动作来实现基于指令的图像编辑。

东京大学联合Adobe提出的InstructMove是一种基于指令的图像编辑模型&#xff0c;使用多模态 LLM 生成的指令对视频中的帧对进行训练。该模型擅长非刚性编辑&#xff0c;例如调整主体姿势、表情和改变视点&#xff0c;同时保持内容一致性。此外&#xff0c;该方法通过集成蒙版、…

海思Linux(一)-Hi3516CV610的开发-ubuntu22_04环境创建

目 录 前 言 一、芯片介绍 二、环境搭建 2.1 前提准备 2.2 虚拟机创建 2.3 ubuntu环境安装 2.4 基础ubuntu环境搭建 2.5 使用MobaXterm登陆ubuntu 前 言 芯片选型:HI3516CV610 选择的开发板是&#xff1a;酷电科技馆的Hi3516CV610-MINI开发板 上一篇文章&#xf…

vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。

vue elementUI Plus实现拖拽流程图&#xff0c;不引入插件&#xff0c;纯手写实现。 1.设计思路&#xff1a;2.设计细节3.详细代码实现 1.设计思路&#xff1a; 左侧button列表是要拖拽的组件。中间是拖拽后的流程图。右侧是拖拽后的数据列表。 我们拖动左侧组件放入中间的流…

Spring boot 项目 Spring 注入 代理 并支持 代理对象使用 @Autowired 去调用其他服务

文章目录 类定义与依赖注入方法解析createCglibProxy注意事项setApplicationContext 方法createCglibProxy 方法 类定义与依赖注入 Service: 标识这是一个 Spring 管理的服务类。ApplicationContextAware: 实现该接口允许你在类中获取 ApplicationContext 对象&#xff0c;从而…

应用程序越权漏洞安全测试总结体会

应用程序越权漏洞安全测试总结体会 一、 越权漏洞简介 越权漏洞顾名思议超越了自身的权限去访问一些资源&#xff0c;在OWASP TOP10 2021中归类为A01&#xff1a;Broken Access Control&#xff0c;其本质原因为对访问用户的权限未进行校验或者校验不严谨。在一个特定的系统或…

JAVA:Spring Boot 集成 Quartz 实现分布式任务的技术指南

1、简述 Quartz 是一个强大的任务调度框架&#xff0c;允许开发者在应用程序中定义和执行定时任务。在 Spring Boot 中集成 Quartz&#xff0c;可以轻松实现任务的调度、管理、暂停和恢复等功能。在分布式系统中&#xff0c;Quartz 也支持集群化的任务调度&#xff0c;确保任务…

改善 Kibana 中的 ES|QL 编辑器体验

作者&#xff1a;来自 Elastic Marco Liberati 随着新的 ES|QL 语言正式发布&#xff0c;Kibana 中开发了一种新的编辑器体验&#xff0c;以帮助用户编写更快、更好的查询。实时验证、改进的自动完成和快速修复等功能将简化 ES|QL 体验。 我们将介绍改进 Kibana 中 ES|QL 编辑器…

【深度学习入门_基础篇】线性代数本质

开坑本部分主要为基础知识复习&#xff0c;新开坑中&#xff0c;学习记录自用。 学习目标&#xff1a; 熟悉向量、线性组合、线性变换、基变换、矩阵运算、逆函数、秩、列空间、零空间、范式、特征指、特征向量等含义与应用。 强烈推荐此视频&#xff1a; 【官方双语/合集】…

【SpringBoot】当 @PathVariable 遇到 /,如何处理

1. 问题复现 在解析一个 URL 时&#xff0c;我们经常会使用 PathVariable 这个注解。例如我们会经常见到如下风格的代码&#xff1a; RestController Slf4j public class HelloWorldController {RequestMapping(path "/hi1/{name}", method RequestMethod.GET)publ…

VBA(Visual Basic for Applications)编程|excel|一系列网址或文件路径快速转换为可点击的超链接

很多时候&#xff0c;我们需要把导入的数据某一列转换成超链接&#xff0c;比如URL形式的列。 那么&#xff0c;大批量的情况下&#xff0c;无疑一个个手动点击是非常愚蠢的办法&#xff0c;这个时候我们就需要VBA编程来编写宏&#xff0c;通过编写宏来简化这些手动操作并不现…

小程序开发全解析 快速构建高效应用的核心指南

内容概要 小程序开发是当前数字世界中炙手可热的领域&#xff0c;吸引了无数开发者和企业的关注。随着技术的进步&#xff0c;小程序成为了提升用户体验、增强品牌曝光以及增加客户互动的重要工具。了解小程序的基本概念&#xff0c;就像是打开了一扇通往新世界的大门。 在这…

SQL—Group_Concat函数用法详解

SQL—Group_Concat函数用法详解 在LC遇见的一道很有趣的SQL题&#xff0c;有用到这个函数&#xff0c;就借这道题抛砖引玉&#xff0c;在此讲解一下group_concat函数的用法。&#x1f923; GROUP_CONCAT([DISTINCT] expression [ORDER BY expression] [SEPARATOR separator])…

Edge Scdn的应用场景有哪些?

酷盾安全Edge Scdn 具备强大的安全防护能力&#xff0c;通过多层防御机制&#xff0c;如防火墙、DDoS 攻击防护、入侵检测和防御、数据加密等&#xff0c;有效抵御各种网络攻击&#xff0c;包括 DDoS 攻击、CC 攻击、SQL 注入攻击、XSS 跨站脚本攻击等&#xff0c;保障网站和应…

流光效果

1、流光效果是什么 在 Unity Shader 中的流光效果是一种动态的视觉效果&#xff0c;通常用于给材质增加一种闪光或光线移动的效果&#xff0c;使物体表面看起来像是有光在流动。这种效果常用于武器光效、能量护盾、传送门等等&#xff0c;可以让物体看起来更加生动富有科技感 …

滑动窗口——串联所有单词的子串

一.题目描述 30. 串联所有单词的子串 - 力扣&#xff08;LeetCode&#xff09; 二.题目解析 题目前提&#xff1a;s是一个字符串&#xff0c;words是一个字符串数组&#xff0c;里面所有的字符串的长度都是相等的。 题目要求&#xff1a;找到s中的一段连续的子串&#xff0…

【微软,模型规模】模型参数规模泄露:理解大型语言模型的参数量级

模型参数规模泄露&#xff1a;理解大型语言模型的参数量级 关键词&#xff1a; #大型语言模型 Large Language Model #参数规模 Parameter Scale #GPT-4o #GPT-4o-mini #Claude 3.5 Sonnet 具体实例与推演 近日&#xff0c;微软在一篇医学相关论文中意外泄露了OpenAI及Claud…