Java 1.5新增的一项特性-注解。注解也称为元数据,为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便的使用这些数据。注解不直接对源代码产生作用,源码会直接忽略注解。注解的用处在于其他地方:注解可以帮助编译器发现错误,消除警告;在编译期或者部署时,可以通过注解生成代码或其他文件;注解还可以在运行时发挥作用。注解的最广泛的应用是减少配置文件的编写,Java主流的框架都依赖配置文件运行,程序员为了实现某个功能,要写一份业务代码(也就是Java代码),同时还要在另一个文件编写配置信息(通常是xml)。注解的出现提供了一种将业务代码与配置代码统一的方式,减少了编写累赘的配置文件,已经极大的影响了程序员的编码方式。
注解的使用
注解可以用来标注类,方法,域,参数,局部变量等,注解的使用也很简单,除了@符号外,其他的跟Java的基本语法一致:
@Override
public void fromBase() { ..... }
注解一般会包含一些元素以表示某些值:
@Auther (auther = "cxy")
public class MyAnnotaion { .... }
没有元素的注解称为标注注解,如果一个注解只有唯一的元素,且这个元素名为value,那么在使用注解的时候可以省略元素名,如@SuppressWarning只有一个元素value,那么在使用@SuppressWarnings来消除警告时,就可以省略value了:
@SuppressWarings("unchecked")
public void method() { ...... }
在Java中,可以对同一个目标多次使用同一个注解,这叫做重复注解(Repeating Annotation),注意这是Java8新增的特性:
@Auther( auther = "cxy" )
@Auther( auther = "yhy" )
pubic class MyAnnoation { ...... }
预定义注解和元注解
Java SE内置了5种注解,定义在java.lang中:
@Override,表示当前的方法定义将覆盖超类中的方法,如果方法签名不正确,编译器可以根据该注解发出错误提示,标注注解;
@Deprecated,标记目标已经过时,如果程序员使用了注解为@Deprecated的元素,编译器会发出警告信息;
@SuprressWarnings,关闭不当的编译器警告信息,@SuppressWarnings只有一个名为value的元素,故在使用时可以忽略元素名,value是String[]类型,可以传一字符串数组,如@SuppressWarnings( { "unchecked","deprecated" } )
@SafeVarargs,表示标注的构造方法或者方法不会在参数上执行潜在的不安全的操作,只能标注构造方法或者方法,Java 1.7新增;
@FunctionalInterface Java 8新增;
以上的5中注解是Java给我们定义好的,可以直接使用,但是这远远不够啊,大部分时间还是需要我们自己定义,Java为我们提供了4中元注解,元注解就是用来创建其他注解的注解,且来看:
@Target,表示注解可以用于什么地方,元素由枚举类ElementType提供,包括
ElementType.ANNOTATION_TYPE -
可用于注解类型
ElementType.CONSTRUCTOR
- 可以用于构造方法
ElementType.FIELD
- 用于域,或者叫做属性,或者叫做成员变量
ElementType.LOCAL_VARIABLE
- 局部变量声明
ElementType.METHOD -
用于方法声明
ElementType.PACKAGE
- 用于包声明
ElementType.PARAMETER
- 用于参数声明
ElementType.TYPE -
类,接口(包括注解类型)或enum声明
@Retention,表示在什么级别保存该注解信息,元素有枚举类RetentionPolicy提供:
RetentionPolicy.SOURCE
– 源码级别,注解将被编译器丢弃
RetentionPolicy.CLASS
– 注解在class文件中可用,但会被VM丢弃
RetentionPolicy.RUNTIME
– VM运行时也会保留注解,可以通过反射机制读取注解信息
@Documented,注解将包含在Javadoc中,默认不包含
@Inherited,允许子类继承父类的注解,默认不继承
在Java 8中又提供了一个新的元注解@Repeatable,表示该注解可以多次用于同一目标。
自定义注解
注解其实是一种接口,所以注解的定义看上去跟接口差不多,只是在interface前面多了@,
@Target(ElementType.METHOD,ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Auther {
//注解的元素只能是public或者default
public String auther() default "cxy";
String date()
}
在注解的元素中可以使用默认值,在使用该注解时,如果没有对该元素赋值,那么它就是默认值。在使用默认值时,元素不能有不确定的值,而在定义元素默认值时,不能以null做为其值。用于注解的元素也有限制:
- 基本类型,int,double等,不包括包装类型
- String
- Class
- enum
- Annotaion
- 以上类型的数组
如果使用了其他类型,编译器会报错。有了注解就可以使用了
//auther有默认值,可以不用显式赋值
@Auther(date = "2014-08-07")
public void f() { ...... }
//date没有默认值,必须赋值
@Auther(auther = "yhy",date = "2014-08-07")
public void other() { ...... }
有一点需要注意的是,注解中的所有元素都必须有值,要么在定义注解接口的时候给出默认值,要么在使用的时候显式的赋值。
使用注解
有了注解,如果无法使用,那么它不会比注释更有用。Java提供了一个类AnnotationElement用于反射的获取注解信息,所以它只能处理@Retention为RUMTIME的注解,这个接口有四个方法,分别是:
<T extends Annotation> T getAnnotation(Class<T> annotationClass):返回指定类型的注解
Annotation[] Annotation[] getAnnotations():返回该元素上的所有注解
Annotation[] getDeclaredAnnotations():返回直接作用在该元素上的注解,不包括继承的注解
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass):该元素是否有指定的注解
Class,Field,Method等类均实现了该接口,所以我们可以通过Java的反射机制来获得类,构造器,方法,字段上的注解信息,可以举一个小例子
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 定义自己的注解
* 该注解可用于类,构造方法,方法,字段
* 该注解作用于运行时
*/
@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
int id() default -1;
String author() default "cxy";
String date() default "2014-08-07";
String description();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface OnlyClass {
String description() default "只能在类型上使用该注解";
}
//使用自定的注解标注类
@MyAnnotation(id = 1,description = "这是一个用来演示如何处理注解的类")
@OnlyClass
public class AnnotationProcessor {
@MyAnnotation(id = 2,description = "类的实例域")
private String addr = "China";
private String phone = "010-84950493";
@MyAnnotation(id = 3,description = "类的实例方法")
public void f() {
System.out.println("----------------------");
}
//打印注解的信息
public static void print(MyAnnotation clanno) {
System.out.println("author: " + clanno.author() + "\nid: " + clanno.id() + "\ndate: " + clanno.date() + "\ndescription: " + clanno.description());
}
public static void main(String[] args) {
Class<AnnotationProcessor> clazz = AnnotationProcessor.class;
//获取类上的所有注解
Annotation[] annos = clazz.getAnnotations();
for(Annotation anno : annos) {
//注解其实跟类型无异,也可以使用instanceof
if(anno instanceof MyAnnotation)
print((MyAnnotation)anno);
else {
System.out.println("这是一个OnlyClass注解,其描述是:" + ((OnlyClass)anno).description());
}
}
//逐字段获取其上的注解信息
Field[] feilds = clazz.getDeclaredFields();
for(Field f : feilds) {
if(f.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation fanno = f.getAnnotation(MyAnnotation.class);
print(fanno);
}else {
System.out.println(f.getName() + "没有MyAnnotation注解");
}
}
//逐方法获取其上的注解信息
Method[] methods = clazz.getDeclaredMethods();
for(Method method : methods) {
if(method.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation manno = method.getAnnotation(MyAnnotation.class);
print(manno);
}else {
System.out.println(method.getName() + "没有MyAnnotation注解");
}
}
}
}
自从Java 6后有了更好的处理注解的API,javax.annotation.processing包里有更强的工具,只是还未涉猎。暂且行文至此,还有Java 8新增的若干注解特性还有待学习。
转载请注明出处:喻红叶《Java Annotation》
分享到:
相关推荐
Java Annotation 是 JDK5.0 引入的一种元数据机制,它允许程序员在代码中嵌入额外的信息,这些信息可以被编译器、构建工具或运行时系统用来执行特定的任务。Annotation 提供了一种安全、灵活的方式来描述代码的属性...
Java 注解(Annotation)是Java语言提供的一种元编程机制,它允许程序员在源代码的各个元素(如类、方法、变量等)上添加信息。这些信息可以被编译器或运行时系统用来验证代码、执行特定操作或者提供额外的运行时...
通过上述示例中的JavaAnnotation压缩包,你可能包含了注解的使用示例、源码以及相关的博客文章。源码可以帮助你理解注解的实际应用,而博客文章可能深入解释了注解的工作原理和最佳实践。学习这些材料,将有助于你...
《Java Annotation手册》 在Java编程语言中,注解(Annotation)是一种元数据,它提供了在编译时或运行时处理代码的一种方式。通过注解,开发者可以向编译器或JVM提供有关代码的附加信息,而这些信息通常不直接影响...
Java Annotation,也称为注解,是Java编程语言中的一种元数据机制,用于向编译器、JVM或工具提供有关代码的附加信息。这些信息不直接影响代码的执行,但可以被编译器或运行时环境用来执行特定的操作,如代码分析、...
Java Annotation注解技术是自Java SE 5.0版本引入的一种元编程机制,它允许程序员在源代码的各个层面(如类、方法、变量等)添加元数据,以供编译器、JVM或第三方工具在编译时或运行时进行处理。Annotation简化了...
Java的`javax.annotation.processing.Processor`接口定义了注解处理器的规范。 5. 使用注解 注解可以应用于类、方法、字段、参数、构造函数、包等不同级别。例如: ```java @MyAnnotation("Hello, World!") ...
Java注解(Java Annotation)是Java编程语言中的一个重要特性,它提供了一种元数据的方式,允许程序员在代码中嵌入额外的信息。这些信息可以被编译器、JVM或者特定工具在编译时或运行时读取,用于执行各种验证、生成...
【Java Annotation手册】 Java Annotation是Java编程语言中的一个重要特性,它允许程序员在代码中嵌入元数据,这些元数据不直接影响程序的运行,但可以被编译器、工具或运行时环境用来验证代码、生成文档、实现依赖...
Java Annotation是Java编程语言中的一种特性,用于向编译器、虚拟机或其他工具提供元数据。在《Java Annotation入门》的基础上,这篇手册深入探讨了Annotation的定义、使用和功能。 一、Annotation的本质 ...
【Java Annotation 实例】 Java Annotation 是一种元数据,它允许我们在源代码中嵌入信息,这些信息可以被编译器或运行时环境用于处理代码。Annotation 不是代码本身,但可以影响代码的行为或提供编译时和运行时的...
在《Java Annotation入门》之后的这篇《重难点之JavaAnnotation手册》中,作者深入探讨了Annotation的概念、定义以及其在Java开发中的应用。 一、Annotation是什么? Annotation是一种在代码中添加的特殊注解,用于...
Java 注解(Annotation)是 Java 语言的一种元数据机制,它允许程序员在源代码中嵌入额外的信息。这些信息可以被编译器、IDE、JVM 或其他工具使用,以增强代码的功能,简化开发,提高可维护性。注解并不直接影响代码...
Java Annotation 是一种在Java编程语言中引入的元数据机制,自J2SE 5.0开始可用,由JSR-175规范定义。注释的主要目的是为代码提供附加信息,这些信息可以用来生成文档、追踪依赖关系或执行编译时检查。元数据允许...
如果你想知道java annotation是什么?你可以看看
Java 注解(Annotation)是自 JDK 5.0 版本引入的一种元数据机制,用于向编译器、开发工具和运行时系统提供有关代码的附加信息。它们并不直接影响程序的执行,但可以用于代码分析、编译时验证或者运行时处理。本文将...
Java Annotation,也称为注解,是Java编程语言中的一种元数据,它提供了在代码中附加信息的方式,这些信息可以被编译器、JVM或工具在编译时或运行时处理。注解不会直接影响程序的运行,但可以用于代码分析、验证、...