认识Java注解
阅读原文时间:2023年08月09日阅读:3

1.注解是什么?

注解,元数据的一种形式,提供与程序有关的数据,但又不是程序的一部分。注解对它们注解的代码操作没有直接影响。

附注:元数据是指用来描述数据的数据,更通俗一点,就是描述代码间关系,或者代码与其他资源(例如数据库表)之间内在联系的数据。在Java中,使用Annotation的概念来描述元数据。元数据以标签的形式存在于java代码中,元数据标签的存在并不影响程序代码的编译和执行。

2.注解有什么用?

  • 给编译器提供信息——注解可以被编译器用来检测错误和抑制警告。
  • 编译时和部署时处理——软件工具处理注解信息生成代码、XML文件等等
  • 运行时处理——一些注解适用于在运行时检查。

3.注解被用于哪些地方?

注解可以应用于声明:类,字段,方法,以及其他程序元素的声明。

声明的类上:

@Entity
public class Person{…}

字段上:

public class Person{

@NotNull  
private String name;

}

方法上:

@Override
public String toString(){…}

Java SE 8 发行版,注解也可以应用于使用的类型。下面是一些例子:

创建类实例的表达式中:

new @Inner InnerObject();

类型转换中:

String value = (@NotNull String) jsonObject;

implements语句中:

class UnmodifiableList implements @Readonly List<@Readonly T> { … }

声明抛出的异常中:

void doWork() throws @BaseServiceException ChannelException { … }

像这种形式的注解,称为“类型注解”

4.我们如何使用它?

4.1.声明注解

语法:

[public/abstract] @interface Xxx{
[public/abstract] [dataType] xx();
[public/abstract] [dataType] xx() default x;
}

示例:

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/8 9:30
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public @interface Name {
//名字
String first();
//姓氏
String last();
}

一、这种没有注解类型元素的注解,我们称之为标记注解类型(a marker annotation type),如下例的@Identifier注解;

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/8 8:58
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public @interface Identifier {
}

二、这种只有一个注解类型元素的注解,我们称之为单元素注解类型(a single-element annotation type),如下例的@Age注解;

三、定义注解类型元素时,可以设置默认值,如上例中的@Age注解;

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/7 19:56
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public @interface Age {
/**
* 声明有默认值的注解属性
*/
String value() default "N/A";
}

注意:单元素注解,根据惯例,元素名称为value,如果注解类型元素名称为value,在使用它的时候可以省略名字;否则的话,名字不能省略。如下面示例,Magazine类中对age字段使用@Age注解,就省略了value名称。

四、注解声明的语法,允许除方法声明之外的其他元素声明,如下示例,声明注解要使用的枚举:

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/8 9:06
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public @interface Sex {
enum SEX { MALE, FEMALE }
SEX value();
}

五、在使用注解时,声明的类、方法、变量等其他程序元素上面可以有多个注解,如下面示例中对Magazine类中的age字段就使用了@Age注解和@SuppressWarning注解:

六、声明注解的元素,只能是以下类型:

  • 所有基本类型(boolean,char,byte,short,int,long,float,double)
  • String
  • Class
  • enum
  • Annotation
  • 以上类型的数组类型

如下面示例中,Description注解里面元素的类型就包括String、long、enum对象Version、String数组和Class这几种;

七、要想使@Description出现在Javadoc-generated文档中,你必须用@Documented注解给@Description注解定义。

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/7 14:01
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public @interface Author {
Name name();
}

以下声明一个要示例中要使用的枚举:

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/7 17:19
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
public enum Version {

V\_1\_0("1.0"), V\_2\_0("2.0");

public String getVersion() {  
    return version;  
}

public void setVersion(String version) {  
    this.version = version;  
}

private String version ;

private Version(String version) {  
    this.version = version;  
}

}

package org.springmorning.demo.javabase.annotation;

import java.lang.annotation.Documented;

/**
* @author 春晨
* @date 2019/1/7 17:08
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
interface Formatter {}

class CommonFormat implements Formatter {}
class SpecificFormat implements Formatter{}

@Documented
public @interface Description {
//作者
Author author();
//日期
long date();
//版本
Version version() default Version.V_1_0;
//上次修改时间
String lastModified() default "N/A";
//由谁修改
String lastModifiedBy() default "";
//贡献者
String[] contributors();
//优先使用的打印格式
Class prettyPrinter();
}

package org.springmorning.demo.javabase.annotation;

/**
* @author 春晨
* @date 2019/1/7 13:59
* Copyright 2019 春晨 https://www.cnblogs.com/springmorning/p/10234764.html
*/
@Description(
author = @Author(name=@Name(first = "晨", last = "春")),
date = 20190102,
version = Version.V_2_0,
lastModified = "2019-01-07 08:11:22",
lastModifiedBy = "张三",
contributors = {"张三","李四"},
prettyPrinter = CommonFormat.class
)
public class Magazine {

@Identifier  
private String id;

@Author(name=@Name(first = "四", last = "李"))  
private String author;

@Age("12")  
@SuppressWarnings("unchecked")  
private int age;

@Sex(Sex.SEX.MALE)  
private String sex;

@Override  
public String toString(){  
    return super.toString();  
}  

}

4.2 预定义注解

Java SE API预定义了一系列的注解类型,这些注解根据其中一些注解类型用于Java编译器,另一些用于其他注解,如以上示例中@Document、@Override和@SuppressWarnings注解。

Java SE 8,预定义的注解有:@Target、@Retention、@Documented、@Inherited、@Repeatable、@Override、@SuppressWarnings、@Deprecated、@SafeVarargs和@FunctionalInterface这十种。

其中,我们把@Target、@Retention、@Documented、@Inherited、@Repeatable这五种注解,称为“元注解”,Java中的元注解专职负责注解其他注解的,用来标示其他注解的适用范围和作用域。

5. 下节继续

下节将给大家讲解,元注解@Target的使用。