Java的annotation

本文深入解析Java注解的原理及应用,包括替代传统注释、使用@Deprecated等内置注解,以及如何在运行时访问自定义注解信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从oracle的官方文档来学习annotations:

地址在: [url]http://docs.oracle.com/javase/tutorial/java/javaOO/annotations.html[/url]

总结如下:

Annotations我理解就是程序的一些元数据,没有它程序也是ok的。它的主要用途体现在以下几个方面:

1. 替代以前简单的注释;

比如以前的注释可能是:
/*
author: Benjamin Franklin
date: 3/27/2010
*/


class My Class {}

用Annotations可以写成:
@Author(
name = "Benjamin Franklin",
date = "3/27/2010"
)
class MyClass() { }


再复杂一点的注释:

public class Generation3List extends Generation2List {

// Author: John Doe
// Date: 3/17/2002
// Current revision: 6
// Last modified: 4/12/2004
// By: Jane Doe
// Reviewers: Alice, Bill, Cindy

// class code goes here

}


用Annotations:

@interface ClassPreamble {
String author();
String date();
int currentRevision() default 1;
String lastModified() default "N/A";
String lastModifiedBy() default "N/A";
// Note use of array
String[] reviewers();
}

@ClassPreamble (
author = "John Doe",
date = "3/17/2002",
currentRevision = 6,
lastModified = "4/12/2004",
lastModifiedBy = "Jane Doe",
// Note array notation
reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List {

// class code goes here

}


其中,@interface是定义一个annotation的关键字,看上去像接口,其实不是。
如果要让@ClassPreamble的信息出现在javadoc生成的文档中,你必须给刚才定义的@ClassPreamble加上@Documented这个保留的annotation。

如下所示:

// import this to use @Documented
import java.lang.annotation.*;

@Documented
@interface ClassPreamble {

// Annotation element definitions

}



2. 编译器保留的注解, 例如@Deprecated, @Override, 和 @SuppressWarnings.

@Deprecated意思是这个方法过时了,你最好不要再用了,你用我就给你来个warning;
@Override是提示你这个方法是覆盖了父类的一个方法;
@SuppressWarnings是告诉编译器这个方法可能会抛出warning,但你不要告诉我啦。

3. 在runtime用这些注解信息;
一般的用法在runtime的时候JVM不会load这些annotation信息,如果要让runtime知道,就要使用java.lang.annotation.RetentionPolicy了,这是个enum,有三个可选值,
分别是
[list]
[*]CLASS:annotation会被记录在class文件里但不会被jvm load。
[*]RUNTIME:记录在class文件里也会被jvm load,可以通过反射读取。
[*]SOURCE:会被compiler丢弃。
[/list]

具体看下面这个例子:

先定义一个annotation:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Test_Target {
public String doTestTarget();
}


@Retention(RetentionPolicy.RUNTIME) 就是上面所说的在runtime时候我也要知道注解的信息。

@Target(ElementType.FIELD) 是指这个注解可以加在Field前面(所以你加到方法签名会编译不过的),java.lang.annotation.ElementType也是一个enum,其他可选择的值包括如下,不翻译了。

CONSTRUCTOR
Constructor declaration
FIELD
Field declaration (includes enum constants)
LOCAL_VARIABLE
Local variable declaration
METHOD
Method declaration
PACKAGE
Package declaration
PARAMETER
Parameter declaration
TYPE
Class, interface (including annotation type), or enum declaration

定义了这个注解,看怎么在runtime时候访问它:

import java.lang.reflect.Field;

public class TestAnnotations {

@Test_Target(doTestTarget="Hello World !")
private String str;

public static void main(String[] args) throws Exception {
// We need to use getDeclaredField here since the field is private.
Field field = TestAnnotations.class.getDeclaredField("str");
Test_Target ann = field.getAnnotation(Test_Target.class);
if (ann != null) {
System.out.println(ann.doTestTarget());
}
}
}



注意在变量str前面使用了定义的注解,在main方法里通过反射获取到了注解中doTestTarget对应的值,所以输出是

Hello World !
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值