19_注解

news2024/11/16 9:43:15

文章目录

  • 注解
    • 注解的作用
    • 注解的语法
    • 注解的使用
  • 元注解
  • 注解处理器
    • 案例
  • 注解VS配置文件
  • 注解的应用

注解

  • Annotation是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理
  • 可以把Annotation理解为一个标签
  • 注解是不允许继承

注解的作用

  • 通过使用Annotation,程序开发人员可以在不改变原有逻辑的情况下,在源文件嵌入一些补充信息
  • Annotation就像修饰符一样被使用,可用于修饰构造器方法成员变量参数…,这些信息被存储在Annotation的“属性名=属性值”对中。

注解 VS 注释

  • 相同点
    • 都是用来传递额外信息的
  • 不同点
    • 注解可以参与编译,注释不行
    • 注解有使用范围,注释没有(想咋写咋写)
    • 注解作为一种数据类型,跟class interface具有同等地位

注解的语法

权限修饰符 @interface 注解名字{
    // 注解体定义
    属性类型 属性名();
    属性类型 属性名();
    属性类型 属性名();
    ......
}

属性类型:
基本数据类型
String类型
Class类型
注解类型
枚举类型
以及以上类型的数组形式

eg:

public @interface MyAnnotation {
    int a1();

    double a2();

    String a3();

    Class a4();

    MyAnnotation2 a5();
    
    String[] str();
    
    Season a6();
}

@interface MyAnnotation2{
    
}

enum Season{
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

注解的使用

@注解名(属性1=属性值,属性2=属性值)

注意事项:

  • 每个属性都要赋值

  • 可以不赋值,但是要有默认值, default

  • 数组形式赋值 {}

  • 如果只有1个属性, 名字叫value, 可以简化赋值

  • 如果属性类型是引用类型, 不能是null

eg:


public class Demo {
    public static void main(String[] args) {

    }

    @MyAnno0(hobby = {"football", "basketball", "tennis"})
    @MyAnno1("zs")
    public static void func() {

    }
}

@interface MyAnno0 {
    // 注解体
    int age() default 0;

    String name() default "zs";

    String[] hobby();
}

@interface MyAnno1 {
    // 注解体
    String value();
}


元注解

  • 描述注解的注解(注解的注解)
  • 元数据 meta data

常用元注解:

  • @Retention元注解,来定义我们自己定义的注解的保留级别

    • RetentionPolicy.RUNTIME

    • RetentionPolicy.CLASS 默认

    • RetentionPolicy.SOURCE

  • @Target元注解,注解可以作用的目标

    • 对于注解而言,可以作用的目标:

        1. 整个类 ElementType.TYPE
        1. 成员变量 ElementType.FIELD
        1. 构造方法 ElementType.CONSTRUCTOR
        1. 成员方法 ElementType.METHOD

eg:

在这里插入图片描述


注解处理器

eg:


public class Demo {
    public static void main(String[] args) 
            throws ClassNotFoundException, NoSuchMethodException {
        // 获取字节码文件对象
        Class<?> c = Class.forName("com.csdn.Demo");

        // 得到方法对象
        Method loginMethod = c.getDeclaredMethod("login");

        // 判断方法上面是否使用注解了
        boolean annotationPresent = loginMethod.isAnnotationPresent(Login.class);

        if(annotationPresent){
            // 获取注解实例
            Login loginAnnotation = loginMethod.getAnnotation(Login.class);
            // 获取注解信息
            String password = loginAnnotation.password();
            String name = loginAnnotation.name();
            // 打印
            System.out.println("password = " + password);
            System.out.println("name = " + name);
        }
        else{
            System.out.println("未使用注解");
        }
    }
    @Login
    public static void login(){

    }
}

// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Login{
    // 属性值
    String name() default "admin";

    String password() default "admin";
}

案例

定义2个注解 :

  • AgeLimit 属性 maxAge minAge

  • NameLimit 属性 length

定义学生类Student 年龄18-25之间 名字长度不超过5

eg:


StudentFactory自己定义的类:
public class StudentFactory {
    static Class studentUtils;

    static {
        try {
            studentUtils = Class.forName("com.cskaoyan.Demo0112.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 提供一个获取学生对象的方法
    public static Student getInstance(String name, int age)
            throws NoSuchFieldException, NoSuchMethodException,
            InvocationTargetException,
            InstantiationException, IllegalAccessException {
        // 通过字节码文件获取对象

        // 判断名字
        judgeName(name);

        // 判断年龄
        judgeAge(age);

        // 获取构造方法
        Constructor declaredConstructor = 
        studentUtils.getDeclaredConstructor(String.class, int.class);

        // 破解
        declaredConstructor.setAccessible(true);

        // newInstance 创建对象
        Student student = (Student) declaredConstructor.newInstance(name, age);

        // 最终返回一个学生对象
        return student;
    }

    private static void judgeAge(int age) throws NoSuchFieldException {
        // 获取age成员变量对象
        Field ageField = studentUtils.getDeclaredField("age");
        // 是否使用注解
        boolean annotationPresent = ageField.isAnnotationPresent(AgeLimit.class);
        if (annotationPresent) {
            // 获取注解实例
            AgeLimit ageLimit = ageField.getAnnotation(AgeLimit.class);
            // 拿到注解信息
            int min = ageLimit.minAge();
            int max = ageLimit.maxAge();
            // 是否在范围内
            if (age < min || age > max) {
                throw new IllegalArgumentException("age is illegal");
            }
        }
    }

    private static void judgeName(String name) throws NoSuchFieldException {
        // 获取name成员变量
        Field nameField = studentUtils.getDeclaredField("name");
        // 是否使用注解
        boolean annotationPresent = nameField.isAnnotationPresent(NameLimit.class);
        if (annotationPresent) {
            // 获取注解实例
            NameLimit namelimit = nameField.getAnnotation(NameLimit.class);
            // 拿到注解信息
            int length = namelimit.length();
            // 是否在范围内
            if (name.length() > length) {
                throw new IllegalArgumentException("name is illegal");
            }
        }
    }
}




main函数:
public class Demo {
    public static void main(String[] args)
            throws NoSuchFieldException, InvocationTargetException,
            NoSuchMethodException, InstantiationException,
            IllegalAccessException {
        StudentFactory.getInstance("zs",18);

        StudentFactory.getInstance("ww",1);
    }
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface AgeLimit{
    int maxAge() default 25;
    int minAge() default 18;
}

@interface NameLimit{
    int length();
}

class Student{
    @NameLimit(length = 5)
    String name;
    @AgeLimit
    int age;

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

注解VS配置文件

配置文件
优点:可配置,不用改源码。管理方便
缺点:不直观,开发效率低

注解
优点:直观开发效率高
缺点:硬编码,修改之后需要重新编译运行,难以和代码分开独立管理

注解的应用

SE :

  • @Test
  • @Override(提供一个额外的信息,方法是重写父类中的方法)
  • @Deprecated(提供一个额外的信息,方法过时了)
  • @FunctionalInterface

EE :

  • @WebService

框架

  • @AutoWired
  • @Service
  • @Mapping
  • @Data
  • @Parm

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++内存管理机制(侯捷)笔记2

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 下面是第二讲allocator具体实…

记录汇川:H5U与Fctory IO测试10

主程序&#xff1a; 子程序&#xff1a; IO映射 子程序&#xff1a; 自动程序 Fctory IO配置&#xff1a; HMI配置&#xff1a; 实际动作如下&#xff1a; Fctory IO测试10

苹果电脑Markdown写作工具:ulysses mac软件介绍

ulysses for mac是一款Markdown写作工具&#xff0c;支持Markdown拼写检查、语音识别、iCloud同步、版本管理等功能&#xff0c;并且可以导出为 PDF、word、RTF、TXT、Markdown、HTML 和 ePub等文件格式。 ulysses for mac软件介绍 适用于Mac&#xff0c;iPad和iPhone的终极写…

Casper Labs 与 IBM Consulting 合作,AI透明度、审计能力的新方案

​ “全新解决方案&#xff0c;旨在帮助企业更有效地管理训练数据&#xff0c;这些数据由不同的组织通过生成式人工智能系统产生” 企业区块链软件和服务提供商 Casper Labs 与 IBM Consulting 共同宣布&#xff0c;它们将联手推出新的解决方案&#xff0c;以帮助客户在其人工…

P5736 【深基7.例2】质数筛题解

题目 输入n个不大于105的正整数。要求全部储存在数组中&#xff0c;去除掉不是质数的数字&#xff0c;依次输出剩余的质数。 输入输出格式 输入格式 第一行输入一个正整数n&#xff0c;表示整数个数。 第二行输入n个正整数&#xff0c;以空格隔开。 输出格式 输出一行&a…

Spring MVC 异常处理器

异常处理器 如果不加以异常处理&#xff0c;错误信息肯定会抛在浏览器页面上&#xff0c;这样很不友好&#xff0c;所以必须进行异常处理。 异常处理思路 系统的dao、service、controller出现都通过throws Exception向上抛出&#xff0c;最后由springmvc前端控制器交由异常处…

专业130+总400+哈尔滨工业大学803信号与系统和数字逻辑电路考研经验哈工大,电子信息,信息与通信工程,信通

今年专业课803信号与系统和数字逻辑130总分400如愿考上哈尔滨工业大学电子信息&#xff08;信息与通信工程-信通&#xff09;&#xff0c;总结了一些各门课程复习心得&#xff0c;希望对大家复习有帮助。 数学一 资料选择&#xff1a; ①高数&#xff1a;张宇强化班 ②线性…

spring Security源码讲解-Sevlet过滤器调用springSecurty过滤器的流程

承接上文 上一节 http://t.csdnimg.cn/ueSAl 最后讲到了过滤器收集完成注入容器&#xff0c;这节我们来讲Security的Filter是怎么被Spring调用的。 我们先看webSecurity的performBuild方法(), 也就是说&#xff0c;最终返回的过滤器对象实例有两种情况当我们配置debugEnabl…

UIUC CS241 讲义:众包系统编程书

原文&#xff1a;angrave/SystemProgramming 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 欢迎来到 Angrave 的众包系统编程维基书&#xff01;这个维基是由伊利诺伊大学的学生和教师共同建立的&#xff0c;是伊利诺伊大学 CS 的 Lawrence Angrave 的众包创作实验。…

SwiftUI 为任意视图加上徽章(Badge)而想到的(下)

概览 在 SwiftUI 为任意视图加上徽章(Badge)而想到的(上) 这篇文章中,我们讨论了如何使用 Preference 技术打造 SwiftUI 中任意视图上徽章的实现。 虽然,我们完成了一系列挑战最后基本得偿所愿,不过在上篇的实现中仍有些许不尽如人意之处。 在本篇博文中,您将学到如下…

安卓(雷电)模拟器清除屏幕密码[亲测可用]

1、设置磁盘可写 启动模拟器&#xff0c;然后在模拟器的设置界面&#xff0c;设置磁盘共享为可写入&#xff0c;重启模拟器&#xff0c;如下图&#xff1a; 2、找到模拟器目录 返回桌面&#xff0c;右键模拟器图标&#xff0c;打开文件所在目录&#xff0c;如下图&#xff1a…

实现稳定的联合显著性检测和联合目标分割

1 Title Toward Stable Co-Saliency Detection and Object Co-Segmentation(Bo Li; Lv Tang; Senyun Kuang; Mofei Song; Shouhong Ding)【IEEE Transactions on Image Processing 2022】 2 Conclusion This paper present a novel model for simultaneous stable co-saliency…

恼人的“龙天“(䶮)--谈谈从GBK转到GB18030的特殊情况

背景 最近在做一个去O迁移适配&#xff0c;刚好也有友商在一起做&#xff0c;两边测试方式不一样。友商先遇到了一个问题&#xff0c;就是在ORACLE中某个的2字节GBK字符到迁移到友商的库中变成了4字节&#xff0c;刚好那个字段在这个字是2字节的时候&#xff0c;已经存满了&am…

Vue.js设计与实现阅读-2

Vue.js设计与实现阅读-2 1、前言2、框架设计的核心要素2、1 提升用户体验2、2 控制代码体积2、3 Tree-Shaking2、4 特性开关2、5 错误处理 1、前言 上一篇我们了解到了 命令式和声明式的区别&#xff0c;前者关注过程&#xff0c;后者关注结果了解了虚拟dom存在的意义&#x…

Excel地址

解题思路&#xff1a; 根据题中歪歪和笨笨的话可以有两种解法。 1.输入的数为多大&#xff0c;则循环1多少次&#xff0c;当值为27时就要进行进位操作。这时要分情况讨论。 当集合中元素为一个时&#xff0c;如26&#xff0c;则需要变为1 1&#xff0c;集合元素个数加一。 当…

C语言指针(一)

目录 1.什么是指针 2.指针变量和地址 1.解引用操作符 2.指针变量类型的意义 3.void*指针 4.const修饰指针 1.const放在*左边 2.const放在*右边 3.指针的运算 1.指针加减整数 2.指针减指针 3.指针比较大小 4.野指针 1.没有给指针变量初始化 2.指针指向的空间释放 …

MES系统中的设备管理及设备数据采集

随时工厂数字化建设的大力推进&#xff0c;设备管理的效率得到了很大的提升&#xff0c;特别是作为机加工企业&#xff0c;设备是整个企业非常重要的核心资产。 一、设备进行数据采集面临痛点&#xff1a; 设备数据状况无法获取与掌握 设备老旧&#xff0c;信息化基础差&…

制造知识普及--MES系统中的调度排产管理

要想弄清楚MES系统调度排产的管理机制&#xff0c;则要首先搞清楚车间调度排产是一套怎样的工作流程&#xff0c;它的难点在什么地方&#xff1f; 生产调度指的是具体组织实现生产作业计划的工作&#xff0c;是对执行生产作业计划过程中发生的问题和可能出现的问题&#xff0c…

Springboot+vue学生考试系统

Springbootvue学生考试系统 演示视频 【Springbootvue学生考试系统】 https://www.bilibili.com/video/BV1gk4y1Q7em/?share_sourcecopy_web&vd_source11344bb73ef9b33550b8202d07ae139b 主要功能&#xff1a; 管理员可以添加题库分配课程教师&#xff0c;指定考试范围指定…

性能测试分析案例-定位服务吞吐量下降

环境准备 预先安装 docker、curl、wrk、perf、FlameGraph 等工具 sudo yum groupinstall Development Tools # 安装火焰图工具 git clone https://github.com/brendangregg/FlameGraph # 安装wrk git clone https://github.com/wg/wrk cd wrk && make && sud…