Java annotation 自定义注释@interface的用法

本文介绍了Java注释的基本概念,包括元数据的概念、J2SE5.0预定义的注释如Override、Deprecated和SuppressWarnings,以及如何自定义注释。同时探讨了注释的使用场景及其在Java开发中的作用。
[i][b]一、什么是注释[/b][/i]
说起注释,得先提一提什么是元数据(metadata)。所谓元数据就是数据的数据。也就是说,元数据是描述数据的。就象数据表中的字段一样,每个字段描述了这个字段下的数据的含义。而J2SE5.0中提供的注释就是java源代码的元数据,也就是说注释是描述java源代码的。在J2SE5.0中可以自定义注释。使用时在@后面跟注释的名字。

[i][b]二、J2SE5.0中预定义的注释[/b][/i]
在J2SE5.0的java.lang包中预定义了三个注释。它们是Override、Deprecated和SuppressWarnings。下面分别解释它们的含义。

1.Override注释:仅用于方法(不可用于类、包的生命或其他),指明注释的方法将覆盖超类中的方法(如果覆盖父类的方法而没有注
释就无法编译该类),注释还能确保注释父类方法的拼写是正确(错误的编写,编译器不认为是子类的新方法,而会报错)
2.@Deprecated注释:对不应再使用的方法进行注释,与正在声明为过时的方法放在同一行。使用被 Deprecated注释的方法,编译器会
提示方法过时警告(”Warring”)
3.@SuppressWarnings注释:单一注释,可以通过数组提供变量,变量值指明要阻止的特定类型警告(忽略某些警告)。数组中的变量指明要阻止的警告@SuppressWarnings(value={”unchecked”,”fallthrough”}))

[i][b]三、自定义注释@interface [/b][/i]
@interface:注释声明,定义注释类型(与默认的Override等三种注释类型类似)。请看下面实例:

注释类1:

package a.test;

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FirstAnno {
String value() default "FirstAnno";
}

注释类2:

package a.test;

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SecondAnnotation {
// 注释中含有两个参数
String name() default "Hrmzone";
String url() default "hrmzone.cn";

}

注释类3:

package a.test;

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Kitto {
String value() default "kitto";
}

使用类:

package a.test;
@FirstAnno("http://hrmzone.cn")
public class Anno {
@Kitto("测试")
private String test = "";
// 不赋值注释中的参数,使用默认参数
@SecondAnnotation()
public String getDefault() {
return "get default Annotation";
}
@SecondAnnotation(name="desktophrm",url="desktophrm.com")
public String getDefine() {
return "get define Annotation";
}

}

测试类:

package a.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class AnnoTest {
public static void main(String[] args) throws ClassNotFoundException {
// 要使用到反射中的相关内容
Class c = Class.forName("a.test.Anno");
Method[] method = c.getMethods();
boolean flag = c.isAnnotationPresent(FirstAnno.class);
if (flag) {
FirstAnno first = (FirstAnno) c.getAnnotation(FirstAnno.class);
System.out.println("First Annotation:" + first.value() + "\n");
}

List<Method> list = new ArrayList<Method>();
for (int i = 0; i < method.length; i++) {
list.add(method[i]);
}

for (Method m : list) {
SecondAnnotation anno = m.getAnnotation(SecondAnnotation.class);
if(anno == null)
continue;

System.out.println("second annotation's\nname:\t" + anno.name()
+ "\nurl:\t" + anno.url());
}

List<Field> fieldList = new ArrayList<Field>();
for(Field f : c.getDeclaredFields()){//访问所有字段
Kitto k = f.getAnnotation(Kitto.class);
System.out.println("----kitto anno: " + k.value());
}
}

}


结合源文件中注释,想必对注释的应用有所了解。下面深入了解。
深入注释:
@Target:指定程序元定义的注释所使用的地方,它使用了另一个类:ElementType,是一个枚举类定义了注释类型可以应用到不同的程序元素以免使用者误用。看看java.lang.annotation 下的源代码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}


ElementType是一个枚举类型,指明注释可以使用的地方,看看ElementType类:
public enum ElementType {
TYPE, // 指定适用点为 class, interface, enum
FIELD, // 指定适用点为 field
METHOD, // 指定适用点为 method
PARAMETER, // 指定适用点为 method 的 parameter
CONSTRUCTOR, // 指定适用点为 constructor
LOCAL_VARIABLE, // 指定使用点为 局部变量
ANNOTATION_TYPE, //指定适用点为 annotation 类型
PACKAGE // 指定适用点为 package
}
@Retention:这个元注释和java编译器处理注释的注释类型方式相关,告诉编译器在处理自定义注释类型的几种不同的选择,需要使用RetentionPolicy枚举类。此枚举类只有一个成员变量,可以不用指明成名名称而赋值,看Retention的源代码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}
类中有个RetentionPolicy类,也是一个枚举类,具体看代码:

public enum RetentionPolicy {
SOURCE, // 编译器处理完Annotation后不存储在class中
CLASS, // 编译器把Annotation存储在class中,这是默认值
RUNTIME // 编译器把Annotation存储在class中,可以由虚拟机读取,反射需要
}
@Documented:是一个标记注释,表示注释应该出现在类的javadoc中,因为在默认情况下注释时不包括在javadoc中的。

所以如果花费了大量的时间定义一个注释类型,并想描述注释类型的作用,可以使用它。

注意他与@Retention(RetentionPolicy.RUNTIME)配合使用,因为只有将注释保留在编译后的类文件中由虚拟机加载,

然后javadoc才能将其抽取出来添加至javadoc中。
@Inherited:将注释同样继承至使用了该注释类型的方法中(表达有点问题,就是如果一个方法使用了的注释用了@inherited,

那么其子类的该方法同样继承了该注释)
注意事项:
1.所有的Annotation自动继承java.lang.annotation接口
2.自定义注释的成员变量访问类型只能是public、default;(所有的都能访问,源作者没用到函数:getDeclaredFields而已)
3.成员变量的只能使用基本类型(byte、short、int、char、long、double、float、boolean和String、Enum、Class、annotations以及该类型的数据)(没有限制,大家可以修改测试一下,就清楚)
4.如果只有一个成员变量,最好将参数名称设为value,赋值时不用制定名称而直接赋值
5.在实际应用中,还可以使用注释读取和设置Bean中的变量。
<think>首先,用户的问题是:“@interfaceJava中是什么意思?”我需要使用中文回答。 根据系统提示,我必须在回答完问题后提出3-5个相关问题,并以“§§相关问题§§”开头输出它们,禁止换行分散。所有内容必须符合规则。 关键点: - 回答必须完整。 - 末尾必须有“§§相关问题§§”行,后跟1. 2. 3. ...格式的问题列表。 - 问题数量:3到5个。 - 基于用户的问题和我的回答提出相关问题。 - 示例格式显示问题列表直接跟在“§§相关问题§§”后。 用户的问题是:“@interfaceJava中是什么意思?”。这是在问Java中的@interface关键字或注释。 在Java中,@interface用于定义自定义注解类型。类似于定义一个接口,但用于注解。 我的回答结构: 1. 解释@interface的含义:它用于创建自定义注解类型。 2. 简要说明用法和重要性。 3. 使用中文描述。 4. 确保回答简洁但信息丰富。 然后,提出3-5个相关问题。这些问题应基于用户的问题和我的回答。示例中显示了代码块,但用户的问题是关于Java的,所以可能需要代码示例。 用户的问题没有代码,但系统提示的示例有代码。所以如果需要,我可以添加一个简单的示例来澄清。 在之前的对话历史中: - 用户问了关于@Target和@Retention的问题,我回答了并提出了相关问题。 - 现在用户问@interface,这相关,因为@interface用于定义注解。 因此,回答: - @interfaceJava中定义注解的关键字。 - 示例:`public @interface MyAnnotation { ... }` - 解释它可以包含元素,如方法。 最终回答: - 解释@interface。 - 可能添加一个简短代码示例,以符合格式。示例格式显示了代码块,所以我应该包括一个。 系统提示的示例格式有代码块:```python ... ```。所以对于Java,我可以使用```java ... ```。 定义相关问题的指南: - 基于问题和回答。 - 例如:其他相关概念、用法、扩展。 相关问题想法: 1. Java中如何定义注解的元素? 2. 注解继承如何工作? 3. 常见内置注解如@Override如何使用? 4. 如何通过反射访问注解? 5. 注解在框架中的应用。 目标是3-5个问题。 最终输出: - 回答部分。 - “§§相关问题§§” - 问题列表:1. ... 2. ... 3. ... 确保没有换行分散:问题列表连续输出,不分行。 完整回答: - 先回答。 - 然后“§§相关问题§§” - 然后问题列表。 写回答: 在Java中,`@interface` 是一个关键字,用于定义自定义注解类型。注解是一种元数据,可以附加到类、方法、字段等元素上,提供额外的信息。例如: ```java public @interface MyAnnotation { String value() default ""; int priority() default 0; } ``` 这定义了一个名为`MyAnnotation`的注解,它有两个元素:`value`和`priority`。 然后提出相关问题。 </think>在Java中,`@interface` 是一个关键字,用于定义自定义注解(annotation)。注解是一种元数据机制,允许开发者为类、方法、字段等代码元素添加额外的标记信息,而不影响程序逻辑。`@interface` 类似于接口定义,但它专门用于创建注解类型,可以包含元素(如方法声明),这些元素指定注解的属性值。例如: ```java // 定义一个自定义注解 public @interface MyAnnotation { String description() default "default text"; int version() default 1; } // 使用该注解 @MyAnnotation(description = "示例注解", version = 2) public class MyClass { // ... } ``` 在此示例中,`@interface` 创建了 `MyAnnotation` 注解,它可以被应用到类、方法等位置,并通过反射在运行时读取其属性值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值