当前位置:首页 > 科技  > 软件

Java注解和反射,你学会了吗?

来源: 责编: 时间:2024-01-18 09:39:36 130观看
导读注解注解(Annotation)是JDK5引入的一种代码辅助工具,其核心作用是对类、方法、变量、参数和包进行标注,通过反射来访问这些标注信息,以此在运行时改变所注解对象的行为,Java中的注解由内置注解和元注解组成。注解与注释Ja

注解

注解(Annotation)是JDK5引入的一种代码辅助工具,其核心作用是对类、方法、变量、参数和包进行标注,通过反射来访问这些标注信息,以此在运行时改变所注解对象的行为,Java中的注解由内置注解和元注解组成。jjg28资讯网——每日最新资讯28at.com

注解与注释

  • Java注解又称之为Java标注,是JDK5开始支持加入源代码的特殊语法元数据
  • 普通的注释在编译后的class文件中是不存在的,而注解附加的信息则根据需要可以保存到class文件中,甚至运行期加载的class对象中

元注解介绍

创建注解

public @interface [AnnotationName]{}

元注解(描述注解的一种方式)

1.@Retention 定义注解的生命周期(source、class、runtime)
2.@Documented 文档注解,会被javadoc工具文档化
3.@Inherited 是否让子类继承该注解
4.@Target 描述注解的应用范围,可选内容如下所示:jjg28资讯网——每日最新资讯28at.com

  • TYPE:可以用来修饰类、接口、注解类型或枚举类型
  • PACKAGE:可以用来修饰包
  • PARAMETER:可以用来修饰参数
  • ANNOTATION_TYPE:可以用来修饰注解类型
  • METHOD:可以用来修饰属性
  • FIELD:可以用来修饰属性(包括枚举常量)
  • CONSTRUCTOR:可以用来修饰构造器
  • LOCAL_VARIABLE:可以用来修饰局部变量

创建使用注解示例

注解的创建方式:jjg28资讯网——每日最新资讯28at.com

  1. 配置元注解,由元注解来声明当前注解的作为范围和声明周期。
  2. 注解中如果需要添加信息,可以用以上方式添加。
  3. 注解信息支持java的基本数据结构。

1.创建注解 @Studyjjg28资讯网——每日最新资讯28at.com

@Target({ElementType.FIELD, ElementType.TYPE}) // 元注解,定义注解的修饰范围,可以设置多个@Retention(RetentionPolicy.RUNTIME) // 元注解,定义注解的声明周期public @interface Study { // 注解内容可以设置值,也可以不设置值    // 其中的属性是支持JAVA的八大属性的 byte、short、int、long、float、double、boolean、char    // 如果属性为value,那么使用时,赋值可以不写 "value ="    String name() default "Neco Deng"; // 表示定义了一个name属性,并且设置了默认值为Neco Deng    String[] mores(); // 表示定义了一个名字为mores的字符串数组属性,并且没有默认值,即该属性需要显示定义}

2.使用注解jjg28资讯网——每日最新资讯28at.com

@Study(mores = {"first", "second"}) // 在类上使用注解,这里必须定义mores, 不然会报错public class Person {    private int id;    @Study(mores = {"first", "second"}) // 在属性上使用注解,这里必须定义mores, 不然会报错    private String name;}

反射

反射(Reflection):在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射。jjg28资讯网——每日最新资讯28at.com

反射的优缺点

  • 通过反射可以使程序代码访问装载到JVM中的类的内部信息,获取已装载类的属性信息,获取已装载类的方法,获取已装载类的构造方法信息。
  • 反射提供了JAVA程序的灵活性和扩展性,降低耦合性,提高自适应能力。
  • 反射会对性能造成一定的影响,同时让代码的可读性变低。

常用的反射API

方法名jjg28资讯网——每日最新资讯28at.com

返回值jjg28资讯网——每日最新资讯28at.com

参数描述jjg28资讯网——每日最新资讯28at.com

Class.forName()jjg28资讯网——每日最新资讯28at.com

获取类的元信息jjg28资讯网——每日最新资讯28at.com

当前类文件的具体位置jjg28资讯网——每日最新资讯28at.com

clazz.getClass()jjg28资讯网——每日最新资讯28at.com

获取类的元信息jjg28资讯网——每日最新资讯28at.com

jjg28资讯网——每日最新资讯28at.com

clazz.getDeclaredFields()jjg28资讯网——每日最新资讯28at.com

获取当前类中的所有属性jjg28资讯网——每日最新资讯28at.com

当前类文件的具体位置jjg28资讯网——每日最新资讯28at.com

setAccessible(true)jjg28资讯网——每日最新资讯28at.com

设置当前属性为可见jjg28资讯网——每日最新资讯28at.com

true或falsejjg28资讯网——每日最新资讯28at.com

getMethods()jjg28资讯网——每日最新资讯28at.com

获取类所有方法jjg28资讯网——每日最新资讯28at.com

jjg28资讯网——每日最新资讯28at.com

invoke(obj)jjg28资讯网——每日最新资讯28at.com

通过反射执行方法jjg28资讯网——每日最新资讯28at.com

类的元信息jjg28资讯网——每日最新资讯28at.com

getAnnotation(class)jjg28资讯网——每日最新资讯28at.com

获取注解jjg28资讯网——每日最新资讯28at.com

需要获取到额注解的Classjjg28资讯网——每日最新资讯28at.com

例子

public class ReflectionDemo {    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException,            InstantiationException, NoSuchMethodException, InvocationTargetException {        // 实例1:通过反射获取到Class元信息        Person person = new Person();        Class<? extends Person> aClass1 = person.getClass(); // 通过getClass获取元信息        Class<?> aClass2 = Class.forName("com.model.Person"); // 通过forName获取元信息        // 实例2:通过反射获取类名,包名        String name = aClass1.getName(); // 全路径类名 > cn.lazyfennec.model.Person        String simpleName = aClass1.getSimpleName(); // 不包含路径 > Person        Package aPackage = aClass1.getPackage(); // 包名 > package cn.lazyfennec.model        System.out.println(name);        System.out.println(simpleName);        System.out.println(aPackage);        System.out.println("===============================");        // 实例3:获取类属性        Field[] declaredFields = aClass1.getDeclaredFields();        for (Field declaredField : declaredFields) {            System.out.println(declaredField);        }        // 实例4:获取类属性的具体的值        person.setId(1);        person.setName("Neco");        for (Field declaredField : declaredFields) {            declaredField.setAccessible(true); // 设置属性可见可访问,处理私有属性无法访问的问题            System.out.println(declaredField.get(person));        }        // 实例4的另一种写法,只是简单的写法,可以进行优化        Object obj = aClass1.newInstance(); // 实例化一个新的对象, 相当于反射中的实例化        declaredFields = obj.getClass().getDeclaredFields();        for (Field declaredField : declaredFields) {            declaredField.setAccessible(true);            if (declaredField.getName().equals("name")) {                declaredField.set(obj, "Neco");            } else {                declaredField.set(obj, 1);            }            System.out.println(declaredField.get(obj));        }        // 实例5:反射获取当前类的方法        Method[] methods = aClass1.getMethods();        for (Method method : methods) {            System.out.println(method.getName());        }        Method method = aClass1.getMethod("getString");        Object invoke = method.invoke(obj);        System.out.println(invoke);        // 实例6:反射获得注解        Study study = aClass1.getAnnotation(Study.class); // 从类中获取注解        System.out.println(study);        String[] mores = study.mores();        String name1 = study.name();        System.out.println("name: " + name1 + " mores: " + mores);        // 从方法上获取注解        methods = aClass1.getDeclaredMethods();        for (Method method1 : methods) {            Study annotation = method1.getAnnotation(Study.class);            if (annotation == null) continue;            String name2 = annotation.name();            String[] mores1 = annotation.mores();            System.out.println("name: " + name2 + " mores: " + mores1);        }        // 从属性上获取注解        declaredFields = aClass1.getDeclaredFields();        for (Field declaredField : declaredFields) {            Study annotation = declaredField.getAnnotation(Study.class);            if (annotation == null) continue;            String annotationName = annotation.name();            String[] annotationMores = annotation.mores();            System.out.println("name: " + annotationName + " mores: " + annotationMores);        }    }}

参考

https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/index.htmljjg28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-64099-0.htmlJava注解和反射,你学会了吗?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Gorm 框架原理&amp;源码解析

下一篇: Jet Brains 2023 开发者生态系统现状

标签:
  • 热门焦点
  • Mate60手机壳曝光 致敬自己的经典设计

    Mate60手机壳曝光 致敬自己的经典设计

    8月3日消息,今天下午博主数码闲聊站带来了华为Mate60的第三方手机壳图,可以让我们在真机发布之前看看这款华为全新旗舰的大致轮廓。从曝光的图片看,Mate 60背后摄像头面积依然
  • 对标苹果的灵动岛 华为带来实况窗功能

    对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 影音体验是真的强 简单聊聊iQOO Pad

    影音体验是真的强 简单聊聊iQOO Pad

    大公司的好处就是产品线丰富,非常细分化的东西也能给你做出来,例如早先我们看到了新的vivo Pad2,之后我们又在iQOO Neo8 Pro的发布会上看到了iQOO的首款平板产品iQOO Pad。虽
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 从 Pulsar Client 的原理到它的监控面板

    从 Pulsar Client 的原理到它的监控面板

    背景前段时间业务团队偶尔会碰到一些 Pulsar 使用的问题,比如消息阻塞不消费了、生产者消息发送缓慢等各种问题。虽然我们有个监控页面可以根据 topic 维度查看他的发送状态,
  • .NET 程序的 GDI 句柄泄露的再反思

    .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 讲故事上个月我写过一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,当时用的是 GDIView + WinDbg 把问题搞定,前者用来定位泄露资源,后者用来定位泄露代码,后面有朋友反
  • Python异步IO编程的进程/线程通信实现

    Python异步IO编程的进程/线程通信实现

    这篇文章再讲3种方式,同时讲4中进程间通信的方式一、 Python 中线程间通信的实现方式共享变量共享变量是多个线程可以共同访问的变量。在Python中,可以使用threading模块中的L
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
Top