Java学习系列文章第二篇:Java中注解的用法

注解定义

注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

注解好处

  1. 生成文档,这是最常见的功能,也是java最早提供的注解。常用的有@see @param @return等;
  2. 跟踪代码的依赖性,实现替代配置文件的功能。比较常见的是Spring框架中基于注解配置。现在的框架都会使用这中配置方式,借此以减少配置文件。
  3. 在编译的时候进行格式检查。如@Override放在方法前,继承的时候你不重载这个方法,编译的时候就能检查的出来。

Java中常见的注解

1.JDK注解
JDK注解有三种,分别是@Override,@Deprecated,@SuppressWarnings。
@Override放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出;

@Deprecated放在方法前表示这个方法已经过时,最好不要用。例如一个接口升级,老版接口中的一个方法不建议使用,而我们又不能删除这个方法,因为可能有些地方在使用,这个时候我们就可以使用这个注解,下次有人调用这个方法的时候,方法名上就会出现一个横线。

@SuppressWarnings这个注解表示忽略警告。如果我们使用一个过时的方法,ide就会出现警告,我们要想忽略这个警告,就可以使用@SuppressWarnings忽略警告

2.Java第三方注解
如Spring框架中的@Autowired,@Service,@Repository,Mybatis中的@InsertProvider,@UpdateProvider,@Options

包java.lang.annotation中包含所有定义自定义注解所需用到的原注解和接口。如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。
该包同时定义了四个注解

  • Documented(用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。)
  • Inherited(自定义的注解标注在父类上不会被子类所继承)
  • Target(作用范围,方法,属性,构造方法等)
  • Retention(生命范围,源代码,class,runtime)

下面我们就用例子来说明他们的用法:
先定义一个注解

package com.dameiweb;

import java.lang.annotation.*;

/**
 * Created by Sam on 18/4/15.
 * Java注解学习
 */

public @interface Description {

}

使用上面的注解

package com.dameiweb;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Sam on 18/4/15.
 * Java注解学习
 */

// 使用了类成员注解
@Description
public class TestAnnotation {

    // 使用了类成员注解
    @Description
    private Integer width;

    // 使用了类成员注解
    @Description
    public TestAnnotation(Integer width) {
        this.width = width;
    }

    public void a(){
        @Description // 使用了局部变量注解
        Map m = new HashMap<>(0);
    }

    public void setWidth(@Description Integer width){ // 使用了方法参数注解

    }
}

编译之后发现没有出现什么错误,不过这个注解好像没有什么用处。下面我们开始完善这个注解,让四个元注解依次上场。四个元注解分别是@Target,@Retention,@Documented,@Inherited。
@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括:

    ElemenetType.CONSTRUCTOR----------------------------构造器声明
    ElemenetType.FIELD --------------------------------------域声明(包括 enum 实例)
    ElemenetType.LOCAL_VARIABLE------------------------- 局部变量声明
    ElemenetType.METHOD ----------------------------------方法声明
    ElemenetType.PACKAGE --------------------------------- 包声明
    ElemenetType.PARAMETER ------------------------------参数声明
    ElemenetType.TYPE--------------------------------------- 类,接口(包括注解类型)或enum声明

@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括:

    RetentionPolicy.SOURCE ---------------------------------注解将被编译器丢弃
    RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但会被VM丢弃
    RetentionPolicy.RUNTIME VM-------将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。

@Inherited 允许子类继承父类中的注解。

自定义注解

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

定义注解格式

public @interface 注解名 {定义体}

注解参数的可支持数据类型:
1.所有基本数据类型(int,float,boolean,byte,double,char,long,short)
2.String类型
3.Class类型
4.enum类型
5.Annotation类型
6.以上所有类型的数组

Annotation类型里面的参数该怎么设定:
第一,只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为defaul默认类型;   
第二,参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和 String,Enum,Class,annotations等数据类型,以及这一些类型的数组.例如,String value();这里的参数成员就为String;  
第三,如果只有一个参数成员,最好把参数名称设为"value",后加小括号.例:下面的例子FruitName注解就只有一个参数成员。

此处评论已关闭