zoukankan      html  css  js  c++  java
  • 一篇文章通俗易懂的让你彻底理解 Java 注解

    很多Java程序员,对Java的注解一知半解,更有甚者,有的人可能连注解是什么都不知道

    本文我们用最简单的 demo , 最通俗最短的语言,带你了解注解到底是什么?

    先来简单回顾一下基础,我们知道,Java 的源文件编辑后,生成 .class 文件,

    1. .Java源文件,这个是源文件时期
    2. 源文件经过编译生成 .class 字节码文件,这个也是编译时期
    3. .class 加载到内存中,就可以用了,这个是运行期间

    如下图
    image

    记住以上知识点,下面和注解有关,我们正式来讲注解
    本文将从以下 2 个方面来讲解注解

    • 1 注解是什么
    • 2 如何定义一个注解
    • 3 如何使用注解

    尤其是第3条,很多人不理解注解,就是因为不知道如何使用注解
    3条本文会用最简单的语言来揭示如何使用

    一 注解是什么?

    一句话,注解就和生活中的标签一样,比如一个人,这个人可能有 学生标签,月光族标签,爱抬杠标签

    二 如何定义一个注解

    语法: public @interface 注解名 { }
    对的, @interface 是个关键字,记住就行了,没有为什么
    定义注解就是用@interface ,后面跟上注解名

    比如定义一个名字叫 info 的注解,如下
    新建一个文件 info.java,代码如下:

    package com.demo;
    
    //定义了一个叫做 info 的注解
    public @interface info {
    
    }
    

    很简单吧,上面就定义了一个叫做 info 的注解,下面有2个问题来了

    • 第一个: info 注解用在什么地方?
      是用到类名上? 还是用在 类的字段上 ? 还是用在类的方法上 ?

    • 第二个:info 注解生命周期(或叫保留策略,我更喜欢叫生命周期)
      注解还有生命周期吗?答案是当然有了

      前面说过,注解类似标签,一个人可能刚毕业,有月光族标签,刚毕业赚的少嘛
      但是有可能过了 3,4 年,技术好了,工资涨上去了,可能就没有月光族标签了

      那么标签有几个生命周期呢?就是本文开头讲的,参考上面的图
      答案是:3 个 ,分别是 源文件期编译期运行期

    就是说:有的注解存在于源文件期,有的标签存在于编译期,有的标签存在于运行期

    ::: tip
    运行期的注解用的最多,本文着重讲运行期间,源文件期,编译期比较简单
    看懂运行期后,可自行学习另外2个

    运行期,也就是注解在运行期还存在
    :::

    我们接下来给 info 注解定义用在类的字段上,并且是存在于运行期间

    先上代码,再解释,代码如下:

    @Target(ElementType.FIELD)          //注解作用在类的字段上
    @Retention(RetentionPolicy.RUNTIME) //注解存在于运行期
    public @interface info {
        
    }
    

    由上面代码可以看到,出现了 @Target , @Retention 注解,那么 @Target , @Retention又是什么?
    答:@Target, @Retention 是元注解,咋又出来一个元注解,可以望文生义:元就是元始的意思,最开始的意思
    举个很简单的例子来帮助了解元注解是什么

    比如开发一款 IOS APP 软件,用 xcode 这个软件开发,那么 xcode软件又是用什么开发的?
    定义一个注解,用元注解
    是不是很类似,如下图
    image

    看过上面的图应该能理解了,什么是元注解了吧,就是为了定义注解用的,知道怎么用就行了
    就比如我们开发软件,要用到各种各样的开发软件的IDE,我们不用管这些IDE软件是哪个软件开发的
    我们只需要知道,元注解就相当于IDE,注解就相当于我们开发的软件,就OK了

    回到上面的info的定义,我们来解释一下 Target,Retention 这 2 个注解的用处以及能取哪些值

    Target 元注解

    用处:用来定义注解的用在的地方,比如是用在类上啊,还是用在字段上啊,还是用在方法上啊等
    取值:我们列出几个常用的就行,其它的自行下去查义即可,如下

    取值 用在哪
    ElementType.TYPE 类或者接口上
    ElementType.FIELD 类的字段上
    ElementType.METHOD 类的方法上
    ElementType.PARAMETER 方法的参数上

    Retention 元注解

    用处:用来定义注解的生命周期(或叫保留策略,我更喜欢叫生命周期)
    取值:就只有3个,如下

    取值 存在于哪个时期
    RetentionPolicy.SOURCE 源文件期
    RetentionPolicy.CLASS 编译期
    RetentionPolicy.RUNTIME 源运行时期

    ::: tip
    元注解都是已经定义好的,我们只管用,只管知道怎么用就行
    就是我们自定义一个注解时才用到元注解,取几个值,定义一下我们的注解用在哪些地方
    存在的时期等,仅此而已
    :::


    通过上面的叙述,我们小小总结一下

    • 注解就是类似标签一样的东西
    • 注解定义是用 public @interface 注解名 { }
    • 注解是有使用的地方和生命周期的
    • 注解能用在类上,字段上,方法上,参数上等
    • 元注解就是用来定义注解的,就像 xcode 软件是用来开发IOS 软件一样的逻辑

    下面我们来讲第三点,也是最重要的一点,我们学会了自定义注解,怎么使用呢?

    三 如何使用注解

    注解一般是和反射一块用的,不懂反射的,不懂Java的大Class的,一定要看看下面的2篇文章
    一篇文章彻底搞懂Java的大Class到底是什么
    一篇文章弄懂 Java 反射的使用

    我们来扩展一下上面的 info注解,代码如下:

    @Target(ElementType.FIELD)          //注解作用在类的字段上
    @Retention(RetentionPolicy.RUNTIME) //注解存在于运行期
    public @interface info {
        String job();       //job属性
        String comment();   //comment属性
    }
    

    对的,你又看到了注解还能定义属性,记住,就按照上面的定义就行了。
    主要看怎么用

    我们定义一个工人类Worker,如下:

    //工人类
    public class Worker {
        //工人的名字
        public String name;
    
        //工人简介方法,打印工作的基本信息
        public void show(){
    
        }
    }
    
    

    很简单的一个类,我们在 name 字段上添加我们定义的info注解,如下

    public class Worker {
    
        //注解是能给属性传值的,job和comment和info定义中的相呼应,对,属性就是这样用的
        @info(job = "工程师",comment = "工作很努力") 
        public String name;
    
        public void show(){
    
        }
    }
    

    上面我们给 name 字段添加了我们自己定义的注解,并且给注解中传了工作的职位是:工程师 ,评价是:工作很努力
    我们想在show()方法中,打印出工作的名字,职位,和评价

    获取注解中的 job和 comment可以通过反射获取 ,注意看注释,如下

    public class Worker {
    
        //注解是能给属性传的,job和comment和定义中的相呼应
        @info(job = "工程师",comment = "工作很努力")
        public String name;
    
        public void show(){
            //1 获取本类的字节码
            Class clz = this.getClass();
    
            //2 获取类中定义的字段
            Field[] fields = clz.getDeclaredFields();
    
            //3 遍历字段,看看哪个字段有info注解
            for (Field field : fields){
                //4 判断此字段上是否有 info 注解
                info annotation = field.getAnnotation(info.class);
    
                //5 如果不为 null ,说明 field上有info注解
                if (annotation != null){
                    //6 通过info注解,获取info注解中的 job和comment
                    String job = annotation.job();
                    String comment = annotation.comment();
    
                    //7 打印出来
                    System.out.println("我是:" + this.name + " 我的职位是:" + job + "  我的评价是:" + comment);
                }
            }
        }
    }
    

    通过上面可以看出,使用注解步骤如下:

    1. 获取类的 Class ,也就是类的字节码
    2. 获取类的所有字段的字码码数组
    3. 遍历字段
    4. 通过 info annotation = field.getAnnotation(info.class) 获取字段上对应的注解
    5. 通过注解,获取注解中传的值

    我们再来写一个 main 函数,调用上面那段代码:如下

    public class Demo1 {
        public static void main(String[] args){
            Worker worker = new Worker();
            worker.name = "待兔,www.helloworld.net 站长";
            worker.show();
        }
    }
    
    

    打印如下:

    我是:待兔,www.helloworld.net 站长 我的职位是:工程师 我的评价是:工作很努力

    本文到此,几乎讲完了,注解的很多其它的东西还没有讲,不过不重要,本文最重要的让你明白什么是注解,怎么定义注解,怎么使用注解
    至于注解其它的知识,比如注解怎么用在方法上,用上类上,等等,都是类似,只需要查一下就行了。
    网上很多文章 ,只要能通过本文把注解弄明白了,了解注解其它的就简单了。

  • 相关阅读:
    Difference between ClassNotFoundException and NoClassDefFoundError 规格严格
    RPM包。。。 规格严格
    Cygwin sshd Apache sshd 规格严格
    查看真实物理CPU个数 规格严格
    工具类网页 规格严格
    探测无线网卡。 规格严格
    DB2 Error 规格严格
    AIX 安装SSH 规格严格
    美国GIS研究的19个方向
    史上最有趣的Readme
  • 原文地址:https://www.cnblogs.com/start1225/p/14883561.html
Copyright © 2011-2022 走看看