Java-注解入门指南

如果你是个Java开发者,一定用过,至少听说过注解。 注解是Java的一种手段,它的官方定义是

In the Java computer programming language, an annotation is a form of syntactic "metadata“ that can be added to Java source code.Classes, methods, variables, parameters and packages may be annotated.

看不懂吧,翻译成中文就是

注解是一种在Java源码上的附带的 metadata,类/方法/变量/参数和包都可以用到注解。

metadata有些翻译称作元数据,字面意思对于初学者来说实在不好理解,通俗的说就是一种"冗余数据",在功能之外的描述性数据。 有了这些基本概念后来看看一个注解怎么定义,怎么使用,还有原理是怎么实现的。 实现原理这块比较复杂,要涉及到class文件的数据结构,初学者可以选择性阅读这块内容,当然对进阶高级开发来说有必要了解一下。 原理这块我们下篇单独讲。

注解的定义

注解--Annotation, 首先有几个方面的概念需要明确

  • 作用对象:@Target
  • 作用域:@Retention

除了这两个之外还有类似于@Inhertied,@Documented 这种语法,这些高级语法我们不准备介绍,在明白了注解的基本脉络后可以自行学习。 一个注解至少需要有@Retention定义才能正常使用和工作。 回想在平时开发中见到的像 @Override,@TargetApi这些系统注解,是由系统开发者预先定义好了,我们再使用。 从这个角度出发可以把注解分成两类, 一种是已经定义好的像 @Override这种,归属于系统注解, 另外一种是 @Target 这种,归属于 元注解, 如果还没晕的话请往下看,晕了的缓一缓,先记住@Target和@Retention这两个注解。

圣人有云,read the fucking source code,下面贴个自定义注解的源码

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Sexual {
    String value() default "Default";
}

一行行解释, 这段代码定义了一个自定义注解 Sexual,定义它的主要方法是用 @interface修饰。 定义完之后使用这个注解的方法跟@Override这种系统注解一样,还是拿一个万年例子类Student来说,

public class Student {
  String name;
  int age;

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

  @Sexual(value="male") // <- 使用注解Sexual
  public static Student createStudent(String name, int age) {
    return new Student(name, age);
  }

  public void displayInfo() {
    System.out.println("name: " + this.name + " age: " + this.age);
  }
}

注释的这一行就使用了@Sexual注解了。

作用对象

现在回到注解的代码里来解释,@Target在参数中的是修饰对象,有以下这些

ElementType.Constructor 构造方法中
ElementType.Field  成员变量和枚举常量
ElementType.Local_Variable   局部变量
ElementType.Method   方法
ElementType.package   包
ElementType.parameter  方法参数
ElementType.type   接口,类,枚举,注解

比如@Sexual中用的是 METHOD,那么这个注解就可以用来修饰方法。

作用域

@Sexual中的Retention是 RUNTIME,除此之外还有 SOURCE, CLASS, 这三个分别表示的意思是

  • Source:注解只在Java源码中可见
  • Class:注解在源码和Class文件字节码中可见
  • Runtime:注解直到在运行时也可见

拿Sexual的代码来做例子,这里用的是 RUNTIME,意为着在运行时我们还可以拿到这个注解和它所附加的数据。

具体的用法,我们在下面这个代码里给出,这段代码在运行时构造一个Student对象,然后从Student中被注解的方法里拿到注解所设定的value值。

使用注解

import java.lang.Class;
import java.lang.reflect.Method;

public class AnnotationDemo {
    public static void main(String[] args) {
      Student michael = Student.createStudent("Michael", 10);
      michael.displayInfo();

      Class clazz = michael.getClass();
      Method[] methods = clazz.getMethods();
      for(Method method : methods) {
        if(method.isAnnotationPresent(Sexual.class)) {
          Sexual sexual = method.getAnnotation(Sexual.class);
          System.out.println("Student: " + michael.name + " sexual: " + sexual.value());
        }
      }
    }
}

简单解释这段代码, 先 createStudent传入了参数构造了对象 michael,这里很简单。 然后我们从 michael对象中拿到它的类,并用 getAnnotation方法拿到类中所注解的内容。 如果你是第一次接触注解,那么需要留意一下,注解是针对类/文件的,它的目标并不是对象,上面的例子我们只是从对象中去拿它的类而已,如果直接通过Student拿类,也是可以的。

解释下这个demo做的事情。 Method类提供了一些提取注解的方法,

  • isAnnotationPresent,检查是否带某个注解
  • getAnnotation,获取对应注解

所以逻辑上是通过反射拿到各个方法之后,检查方法是否有注解,然后拿到这个注解的 value。

定义注解的时候参数是可选的,各种基本类型都可以,像上面我们定义的Sexual就带了个String类型叫value的参数。 在Student类中传入了"male",并且它的类型是RUNTIME,所以在运行时就可以拿到。对应的如果是SOURCE类型的话那在运行时就拿不到了。

注解的应用

上面的例子只是说明了注解的工作流程,对于注解来说应用不止于此。 很多牛逼的框架都是通过注解来工作的,比方在Android上的ButterKnife,你肯定体会过它的方便,只用注解就代替了我们传统的 findViewById等繁琐的重复劳动。 它的原理也就是在编译时通过注解拿到这些方法/对象后,替我们插入 findViewById这些方法。 所以说在通往Java高级开发的路上,总会在某个点发现注解的强大作用,如果能掌握好注解的原理,在理解高级框架上会节省很多时间呢。希望这篇文章能帮你理清注解的脉络,以后遇到了问题可以自学解决。

本文分享自微信公众号 - Android每日一讲(gh_f053f29083b9)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你可以从面试中学到什么?

    讲一下我对面试的一些。。。“偏见”,哈哈,熟悉我的同学们一定要批判的读接下来的内容哈。

    web前端教室
  • SQL中GROUP BY用法示例

    GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

    Awesome_Tang
  • 复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

    从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

    haifeiWu
  • 【系统设置】CentOS 修改机器名

    ken.io
  • 知识体系解决迷茫的你

    最近在星球里群里都有小伙伴说道自己对未来的路比较迷茫,一旦闲下来就不知道自己改干啥,今天我这篇文章就是让你觉得一天给你 25 个小时你都不够用,觉得睡觉都是浪费...

    桃翁
  • 不只是软件,在线也可以免费下载百度文库了。

    不管是学生,还是职场员工,下载各种文档几乎是不可避免的,各种XXX.docx,XXX.pptx更是家常便饭,人们最常用的就是百度文库,豆丁文库,道客巴巴这些下载...

    课代表
  • 「我真的没有改需求」

    非著名程序员
  • 白底黑字or黑底白字,眼睛更喜欢哪一个?

    腾讯大讲堂
  • 今天我就说三句话

    腾讯NEXT学位
  • 这是对付产品经理的一副毒药,程序员慎入

    程序员和产品经理的日常就像是一对天生的冤家,为了需求的实现,几乎天天在争吵。这不,就在昨天各大技术和产品群里一个程序员暴打产品经理的视频火了,被广泛传播。

    非著名程序员

扫码关注云+社区

领取腾讯云代金券