Java中的注解与反射

Java 注解与反射详解(一遍过) Java 注解与反射(一遍过)类的初始化,类缓存,双亲委派机制 阅读详情

目录

注解:

1、什么是注解

2、元注解

3、如何使用注解

4、注解级别应用场景

反射:

反射获取对象实例

反射操作对象字段

反射调用对象方法

注解+反射模式的优势与弊端

优势:

弊端:

总结:


注解:

1、什么是注解

注解本身是一个比较好理解也比较容易学习的东西,但是和一些其他的Java机制结合起来会变得复杂且功能性强大。在普通的日常编程中其实自己使用注解进行开发的情况并不多,注解长什么样呢?

@Override

这个东西想必大家并不陌生吧,这就是一个注解,只不过已经是由Oracle公司开发好的。那么这个注解有什么用呢,单独来说Override这个注解是用来检查父类是否存在这个原方法,不存在则编译错误。

我们进入到Override的源码来看一下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

我们发现是这么一个玩意儿,  这啥啊,这明明啥也没写啊。他是咋能实现这么伟大的功能的。这个注解的详细原理我们待会儿再说。我们先知道其实注解原本就长这样。

我们定义注解的代码就是这么简单:

public @interface Pillow {
}

我甚至直接这样定义也没有问题,这样的注解我就已经可以使用了。这就是注解的定义方式。

2、元注解

我们发现Override注解和我们自定义的注解上有一些不同,怎么Override注解头上还有注解。其实不止是这样,我们进入@Target注解看一下:

Target注解定义头上居然还有一个Target,什么情况,这是在玩套娃吗。

其实这些注解上的注解就是元注解,元注解是用于定义在自定义类型注解上的注解,其中比较重要的两个元注解就是@Retention 和 @Target

先说@Target, 这个元注解的意思是想要将你自定义的注解应用到哪些地方:类上、方法上、参数上、注解上等等,其中应用于注解上的ElementType.ANNOTATION_TYPE就让自定义注解变为了元注解,这种属性可以添加多个,用{}括起来即可。

再说@Retention,这个元注解的意思是你想要将自定义注解保留在哪个阶段,一共有三种:源码级别(SOURCE)、编译级别(CLASS)、运行时级别(RUNTIME),级别逐级递增,大的级别包含小级别时期,比如运行时级别在源码和编译阶段都存在。来做一个练习:

分析@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

答:作用在方法上且保留源码级别

3、如何使用注解

使用注解的方式非常简单,只需在想添加注解的地方加注解就可以了,注意所添加的注解要符合元注解定义。

我们在定义注解的时候,可以给注解添加属性,这些属性必须是基本数据类型、String、Class、枚举类型、注解类型或这些类型的数组,并且可以添加默认值。注意添加属性的时候有()别漏掉。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pillow {
    String value() default "xxx"; // 默认值为xxx
    int id() default 0; // 注意不能用Integer
}

这里定义属性名也有讲究,如果定义的属性名有一个叫value() 那么注意了:

一般使用注解是这样的 @Pillow(value = "run", id = 666)

而如果只有一个value值需要指定的话,就可以这么简写 @Pillow("run"),也就是这么写默认是给value指定值,但如果有两个及以上的值必须要指定的时候就不能简写。

4、注解级别应用场景

刚才我们讲了Rentention来指明注解级别,下面讲解不同级别的应用场景,最主要部分是运行时与反射联合操作的情况

源码级别:源码级别因为其核心是源码,大多应用场景是语法检查与编码,比如@Override就提供了父类检查机制,其原理是编译器内置了对这个注解的处理,就像是定义int a = "123"会编译异常一样。在Lombok中@Data注解自动提供getter和setter等方法,它也是在源码级别,原理是编译期的源码增强技术。

字节码级别:字节码级别是在编译后操作字节码文件,所以多用于字节码增强技术。AOP面向切面编程就是典型的字节码技术通过描字节码中的注解,根据注解信息对类进行修改(如添加代理逻辑、插入日志代码等),但运行时无需保留注解信息。

运行时级别:这也是我们在定义的时候用的最多的一个阶段,其主要是通过编译后通过反射拿到对应注解信息,再对相应的目标进行操作。如果没学过反射,蒙圈是正常的,往下会细讲反射就会慢慢理解。

反射:

反射是 Java 中一种强大的机制,允许程序在运行时获取类的信息、操作类的属性和方法,而无需在编译期知道类的具体信息。简单来说,反射让程序能够 “看透” 类的内部结构,并动态操作它们。

反射都是基于class的,只要拿到一个类的class,就可以知道他里边的全部信息,甚至修改。

下面是反射的常用方法

反射获取对象实例

自定义一个Student类

package com.software.demo18;

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

    public Student() {
    }

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

    private void study(String other) {
        System.out.println(name + "正在学习," + other + "别来沾边!!");
    }

    public String getName() {
        return name;
    }
}

四种方式获取类对象,一般最常用第三种:

        // 1. 通过类名.class获取(编译期已知类)
        Class<Student> cls1 = Student.class;

        // 2. 通过对象.getClass()获取(已知实例)
        Student student = new Student();
        Class<? extends Student> cls2 = student.getClass();

        // 3. 通过Class.forName("全类名")获取(运行时动态加载,最常用)
        Class<?> cls3 = Class.forName("com.software.demo18.Student");

        // 4. 通过类加载器获取
        ClassLoader classLoader = Run.class.getClassLoader();
        Class<?> cls4 = classLoader.loadClass("com.software.demo18.Student");

 获取Student对象实例:

        // 通过构造器获取对象实例
        Constructor<?> constructor = cls1.getConstructor(String.class, int.class);
        Student student2 = (Student) constructor.newInstance("张三", 18);
        System.out.println(student2.name);

反射操作对象字段

我们直接实例化一个Student:

Student student = new Student("李四",21);

在上面我们已经创建好了类对象,这里我们用cls3来演示,这里要说明一下,我们只是拿到了类对象,就只是拿到了类而已。

下面演示如何把李四这个学生的姓名改成张三,这里还要提前说一点,在我们定义的Student类中,只有一个name的get方法,并且属性值都是私有的。那么如何访问私有属性呢?其实这里就用到了反射的特性,可以直接通过操作字节码将私有属性改为共有的就能访问了。方法为setAccessible(true)。

        Student student = new Student("李四",21);

        Class<?> cls3 = Class.forName("com.software.demo18.Student");

        Field name = cls3.getDeclaredField("name");
        name.setAccessible(true); // 修改访问权限
        name.set(student,"张三"); // 传入实例对象和修改后的内容

        System.out.println(student.getName()); // 这里的输出就变成张三了

还有一个问题需要注意,我们虽然修改了访问权限,但是在编码的时候直接访问。原因是反射是通过动态修改,他是在运行时将权限修改,而在源码时期该权限并未修改。

反射调用对象方法

我将调用Student的study方法:

我们还可以通过反射去调对象相应的方法,实现如下:

这里我们还是用李四的实例。

        Student student = new Student("李四",21);

        Class<?> cls3 = Class.forName("com.software.demo18.Student");


        // 第一个参数为方法名,第二个参数以后就是要传入的形参
        Method method = cls3.getDeclaredMethod("study", String.class);                                 
        method.setAccessible(true); // 防止权限不足

        method.invoke(student,"张三"); // 输出"李四正在学习,张三别来沾边!!"

由此我们得出,我们可以通过反射动态的调用对象的任意方法,即使他是私有的。

通过这几个例子,我们初步的了解到了反射的作用,当然我只是演示了反射比较典型的例子,他还有更加强大的功能,详细都在最开始的树形图中。

注解+反射模式的优势与弊端

优势:

提高代码灵活性与动态性

注解定义规则,反射在运行时动态解析,无需硬编码逻辑。

简化配置与逻辑

传统开发中,配置(如 XML)与代码分离,需要手动解析配置。注解 + 反射将配置嵌入代码,反射自动处理。。

支持动态行为定制

反射可以在运行时根据注解信息动态调整逻辑。

弊端:

增大性能开销

通过演示我们发现,反射通过查找类的属性。即使没找到,每一次调用反射的时候也会遍历整个文件,这无疑提高了性能的开销,据统计通过反射调用方法一般比直接调用慢10~100倍。 

绕过编译期检查,提高风险

演示中,我们直接修改了访问权限,调用了私有方法,这就增加了代码风险。

总结:

注解和反射是Java的高级语言特性,他们结合在一起特别在一些框架的开发中起到了举足轻重的作用,在面试中也难免作为面试内容出现。使用其便捷的同时也要注意到性能和安全方面的问题。

Java反射、注解 最近本着不求甚解的态度重温了一下主流框架的源码,所以趁热打铁的总结一下,学习框架或开发框架所必备的基础知识: Java反射 Java注解 注解代码自动生成 Java动态代理 AOP 一、反射 1.1、简介 本文简单总结一下Java反射和注解,反射可以算是必备条件了,基本学习的主流框架中都会看到反射的身影,他的灵活使用也为很多逻辑的扩展提供了可能,通过Java的反射机制,可以在程序中访... 阅读详情

相关推荐

Java:注解和反射

文章目录 学习视频来自于:秦疆(遇见狂神说)Bilibili地址 他的自学网站:kuangstudy 唯有热爱,能抵岁月漫长

希望有点用 2813

java注解和反射

Java注解详解 1. 概念与作用 注解(Annotation)是代码级别的元数据,用于提供编译检查(如@Override)、生成辅助代码(如Lombok)或运行时处理(如Spring的@Autowired)。 2. 内置注解 @Override:检查方法重写 @Deprecated:标记过时代码 @SuppressWarnings:抑制警告 @FunctionalInterface:声明函数式接口 3. 元注解 定义注解行为的元注解包括: @Target:指定注解作用范围(类/方法/字段等) @Reten

m0_71975922的博客 440

实现自己的AI视频监控系统-第一章-视频拉流与解码4(重点)

使用本章节代码请引用此优快云链接,尊重知识、尊重他人劳动。这一小节将正式进入代码实现部分。我们会结合实际业务需要和拉流解码流程实现一个灵活、轻便、易用的视频拉流解码模块,支持多路视频拉流解码且可以动态更新更新内部参数。在开始设计之初,我们首先考虑的是使用大家所熟知的 **OpenCV(cv2.VideoCapture)**来实现拉流和解码功能。它的 API 简单直接,几行代码就能实现从网络流中读取帧,对于快速原型验证来说非常方便。然而,在经过深入的调研和测试后,我们发现 OpenCV 在处理多路视频流、追

soulproficiency的博客 2268

Java注解和反射

不是程序本身,可以对程序作出解释。(这一点和注释(comment)没什么区别)可以被其他程序(比如:编译器等)读取定义在java.lang包下@Override, 重写@Deprecated, 已过时的,不鼓励使用@SuppressWarnings,用来抑制编译时的警告信息负责注解其他注解,它们被用来提供对其他annotation类型作说明@Target,用于描述注解的使用范围(即被描述的注解可以用在什么地方)

layman4444的博客 1402

刚入职,软件测试岗,有点迷茫不知道下一步怎么提升自己

软件测试前景和发展都是不错,已经入了软件测试这行业就坚挺下去

大白的博客 2217

PX4代码解析(1)

前言 做pixhawk飞控有一段时间了,但在学习过程中遇到许多困难,目前网上找不到比较完整的PX4学习笔记,我打算结合自己理解,写写自己对PX4源码的理解,不一定对,只是希望与各位大佬交流交流,同时梳理一下无人机知识。 目前打算分享以下几个内容:代码架构;通信协议;姿态解算算法,控制算法。先这样,后面想到再加。本章先来聊聊px4代码结构 一、代码整体结构 既然要聊px4代码结构,那就先把px4代码结构图放出来,因为px4源码仍然在不断更新迭代,因此老版本与新版本目录结构可能有些不同,我的代码解析参考版本为V

qq_36903625的博客 1万+

Java注解与反射

Java注解与反射

m0_58684211的博客 1195

SAP接口错误查询日志

随着数字经济的迅速发展,企业数字化转型不在只追求“业财一体化”,而是在业务端也想要进行更为精细化的管理,所以很多企业在SAP ERP的基础上,集成更多垂直领域更精细的外围系统,比如销售CRM系统,采购SRM系统,生产MES系统等等,琳琅满目的产品,那对SAP实施来说,系统集成过程中,接口的一些报错查询能力必不可少,今天我们就介绍一下,SAP和CRM系统集成中接口常见的报错。

weixin_43657667的博客 2047

Java之注解与反射

定义:使用@interface定义注解类,自动继承了java.lang.annotation.Annotation接口注意:1.注释类中的每一个方法其实就是配置了一个参数2.方法名就是参数名3.方法返回值类型就是参数类型(返回值只能是基本类型,class,String,enum)4.可以通过default来声明参数的默认值5.注解元素必须要有值6.当只有一个参数时可以隐式代参,多个只能显式代参//注解可以显式赋值,如果没有默认值,我们必须给注解赋值。

2301_81302603的博客 1298

智能水下机器人设计: 基于MATLAB的水下机器人动力学建模和控制系统设计,包括水下环境感知、路径规划和任务执行等

智能水下机器人是指能够在水下自主完成各种任务的机器人,例如探测、勘察、救援等。它具有广阔的应用前景,可用于海洋环境监测、水下考古、海上作业等领域。基于MATLAB的水下机器人设计可以为科研人员和工程师提供强大的建模和仿真工具,帮助他们设计更智能、更高效的水下机器人。智能水下机器人是未来海洋科技发展的重要方向,它将为海洋科学研究、水下考古和海上作业等领域带来新的机遇。MATLAB是一种功能强大的数学和科学计算软件,它可以为智能水下机器人设计提供强大的工具和支持。

走向CTO的路上... 962

【Unity】【2D】用连续图片生成动画Animation的简明步骤

本文介绍了Unity中使用2D连续图片制作2D动画Animation的简明步骤。

O青草O的博客 Unity和游戏制作知识分享 718

Java中注解与反射的详细介绍

Object relationship Mapping -->对象关系映射。

楠寻寻的博客 1489

使用mid360运行lio-livox对比fast-lio2

msg_type为激光雷达发出的数据格式,有livox自定义数据类型格式CustomMsg和ros标准的PointCloud2格式,因此首先需要确定激光雷达端配置的是哪种格式。可以从激光雷达的ros驱动中看到驱动端有三种格式可以选,驱动端的数字2对应lio-livox中的1,驱动端的0对应lio-livox的格式0。如果使用的是Ubuntu18.04编译完成后运行直接成功,如果使用20.04运行会报错,需要修改以下源代码。针对livox-mid360 运行lio-livox的一些问题。

z1872385的博客 1228

java的反射和注解

什么是注解 Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。和注释不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行 时可以获取到标注内容 。当然它也支持自定义 Java 标注。 注解与注释的区别: 注解是给机器看的注释,而注释是给程序员看的提示,编译时自动忽略注释。 注解的使用场景 编译格式检查 反射中解析 生成

weixin_43145539的博客 1235

Google antigravity 不支持你所在地区?手把手教你把账号改成支持地区

Google antigravity功能火爆,但国内老账号根本用不了🤬本文分享几种有效的账号国家地区切换方法,最快几分钟就能让antigravity直接亮起🔥

XiaoqiangClub的博客 2万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

java注解与反射学习总结

1.注解 1.1什么是注解? ◆Annotation是从JDK5.0开始弓|入的新技术. Annotation的作用 : 不是程序本身,可以对程序作出解释.(这一点和注释(comment)没什么区别) 可以被其他程序(比如:编译器等)读取. ◆Annotation的格式: 注解是以"@注释名"在代码中存在的,还可以添加一-些参数值,例 如:@SuppressWarnings(value=“unchecked”) ◆Annotation在哪里使用? 可以附加在package , cla

qq_41784749的博客 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java中的反射与注解总结

Java反射机制经常与注解搭配,出现在各大框架中,是框架的灵魂所在,贯穿了整个框架的构成。在此对这两个Java特性做一个总结。 反射 能够分析类能力的程序成为反射(reflective)---from Java核心技术卷Ⅰ 通过Java的反射机制,可以在程序中访问已经加载到JVM中的Java对象的描述,实现访问、检测、修复和修改描述Java本身对象的功能,Java中的java.lan...

Wayne_Dream的博客 558

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Java反射与注解

java反射和注解 1 注解 1.1 什么是注解? Annotation是从JDK5.0开始引入的新技术 Annotation的作用 不是程序本身,可以对程序作出解释。(这一点和注释(comment)没什么区别) 可以被其他程序(比如:编译器等)读取 Annotation的格式 注解是以“@注解名”在代码中存在的,还可以添加一些参数值 例如:@Suppress Warning(value=“unchecked”). Annotation在哪里使用? 可以附加在package,class,me

weixin_43481234的博客 1532

Java 注解和反射

注解是 JDK 5.0 引入的新技术。注解是不是程序本身,但可以对程序做出解释;可以被其他程序(比如编译器)读取。注解是以 “@注解名” 在代码中存在,还可以添加一些参数,例如 @SuppressWarnings(value=“ubchecked”)。可以加在 package、class、method、field 等上面,相当于给他们添加额外的信息;我么可以通过反射机制编程实现对这些元数据的访问。使用@interface自定义注解时,自动继承了接口。@interface用来声明一个注解;

kezhou的博客 1087

java 注解与反射总结

目录 一、注解 1、内置注解 2、元注解 3、自定义注解 二、反射 1、什么是反射(Reflection )? 2、反射可以实现的功能 3、反射常用方法 测试案例1:类地址等测试 测试案例2:类的相关属性和方法的查看 测试案例3:通过反射动态操作对象及方法 测试案例4:反射操作与普通操作速度对比 测试案例5:注解与反射操作,框架底层逻辑 一、注解 1、内置注解 @Override 注解在方法上 表示重写父类方法,编译时期报错,提高可读性 @Deprecate.

qq_50909707的博客 1003

Java中的注解和反射

Java中的注解和反射

m0_70990872的博客 737

java注解和反射原理_Java中的注解和反射

最近又回顾了一下 Java 中的注解和反射知识点,注解在日常开发中使用很多,但是反射比较少。值得注意的是 Java 的各种框架底层源码中大量使用了注解和反射,阅读源码,这些是基本功,面试中这部分内容也经常问到。这里面概念不多,内容略微有些枯燥,但是通过一些简单的例子,能让我们明白一些基本概念和 API 的使用。所以,说到底,这篇博客只能算是一个简单的笔记,希望对你有帮助。 以前也写过枚举类和注解...

weixin_35803802的博客 1441

【Java】反射和注解

本文详细概括了反射机制和注解在实际开发中的作用,并且还包括了ResourceBundle读取配置文件的详细操作,以及枚举

Answer的博客 1260

java注解与反射

java注释与反射

Imzhipo的博客 688
上一篇: Java中的泛型 (进阶篇)
下一篇: 注解+反射练习
pillow_mycode
博客等级 码龄3年 34粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值