注解(annotation)定义
注解(也被称为元数据–Meta Data)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。
注解在一定程度上是在把元数据与源码文件结合在一起,而不是保存在外部文档中。
注解是真正的语言级的概念,一旦构造出来,就享有编译期的类型检查保护。
注解的使用方式几乎与修饰符的使用一模一样,可以与任何修饰符共同作用于方法,如public,static…
元数据定义:元数据是指用来描述数据的数据,就是描述代码间关系,或者代码与其他资源(如数据库表)之间内在联系的数据。
- 元数据以标签的形式存在于Java代码中。
- 元数据描述的信息是类型安全的,即元数据内部的字段都是有明确类型的。
- 元数据需要编译器之外的工具额外的处理用来生成其他的程序部件。
- 元数据可以只存在于Java源代码级别,也可以存在于编译之后的Class文件内部。
使用注解的好处
注解可以用来生成描述符文件,甚至或是新的类定义,并且有助于减轻编写“样板”代码的负担。通过使用注解,我们可以将这些元数据保存在Java源代码中,并利用annotation API为自己的注解构造处理工具,同时,注解的优点还包括:更加干净易读的代码以及编译期类型检查等。
定义注解
package com.yangyun.chapter.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author yangyun
* @title 定义一个注解
* @Package com.yangyun.chapter.annotation
* @date 2018-12-08 21:41
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedTest {
// 注解成员,只有一个时,必须是value()
boolean value() default true;
}
@Target,@Retention注解都是元注解。
元注解专职负责注解其他的注解,以下四种:
注解 | 释义 |
---|---|
@Target | 表示注解可以用于什么地方 |
@Retention | 表示需要在什么级别保存该注解信息 |
@Documented | 将此注解包含在Javadoc中 |
@Inherited | 允许子类继承父类中的注解 |
ElementType参数:
注解 | 释义 |
---|---|
CONSTRUCTOR | 构造器声明 |
FIELD | 域声明(包括enum实例) |
LOCAL_VARIABLE | 局部变量声明 |
METHOD | 方法声明 |
PACKAGE | 包声明 |
PARAMETER | 参数声明 |
TYPE | 类、接口(包括注解类型)或enum声明 |
RetentionPolicy参数:
注解 | 释义 |
---|---|
SOURCE | 注解将被编译器丢弃 |
CLASS | 注解在Class文件中可用,但会被vm丢弃 |
RUNTIME | vm将在运行期间也保留注解,因此可以通过反射机制读取注解的信息 |
注解类可以没有成员,没有成员的注解称为标识注解。
注解成员
- 成员以无入参、无抛出异常的方式声明;
- 可以通过default为成员指定一个默认值,当然也可以不指定默认值;
- 成员类型是受限的,合法的类型包括原始类型及其封装类、String、CLass、enums、注解类型,以及上述类型的数组类型。
使用注解
package com.yangyun.chapter.annotation;
/**
* @author yangyun
* @title
* @Package com.yangyun.chapter.annotation
* @date 2018-12-08 22:35
*/
public class ForumService {
@NeedTest(value = true)
public void deleteForum(int forumId) {
System.out.println("删除论坛模块:" + forumId);
}
@NeedTest(false)
public void deleteTopic(int postId) {
System.out.println("删除论坛主题:" + postId);
}
}
访问注解
package com.yangyun.chapter.annotation;
import java.lang.reflect.Method;
/**
* @author yangyun
* @title
* @Package com.yangyun.chapter.annotation
* @date 2018-12-08 22:38
*/
public class Test {
public void tool() {
// 得到ForumService对应的Class对象
Class clazz = ForumService.class;
// 得到ForumService对应的Method数组
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
NeedTest nt = method.getAnnotation(NeedTest.class);
if (nt != null) {
System.out.println(nt.value());
}
}
}
public static void main(String[] args) {
Test test = new Test();
test.tool();
}
}