注解是在Java 1.5之后引入的,为的是可以直接在代码中编写元信息。在注解发布之前,如果想要描述代码只能将其写入到其他文件中,例如xml。 注解可以应用于包,类,方法,字段,参数,类型(Java 8之后)。注解并不会直接影响代码,它只是为第三方系统提供代码的元信息,第三方系统通过解析这些注解获取信息,从而执行不同的方法。
注解使用@开头,例如
@Annotation
public void annotatedMethod(){
}
注解同样也可以有参数
@Annotation(
info = "I am an annotation",
counter = "55"
)
public void annotatedMehod() {
...
}
如果只有一个参数,参数名可以省略
@Annotation("I am an annotation")
public void annotatedMehod() {
...
}
多个注解可以同时修饰同一个元素
@Annotation (info = "UauO")
@Annotation2
class AnnotatedClass { ... }
注解有多种用途,最常用的几种方式是:
Java内置了一些常用的注解,例如下面要介绍的元注解,之所以叫元注解是因为它们是修饰注解的注解
自定义注解的关键字是@interface
例如:
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public @interface CustomAnnotationClass
{
public String author() default "danibuiza";
public String date();
}
上述定义了一个注解CunstomAnnotationClass,它由两个参数author和date,author的默认值是 ‘danibuiza’,这个注解可以修饰类,且在运行时可见。 使用注解
@CustomAnnotationClass( date = "2014-05-05" )
public class AnnotatedClass
{
...
}
java.lang.Class
,java.lang.reflect.Method
,java.lang.reflect.Field
等都实现了getAnnotations(),isANnotationPresent(Annotation),getAnnotation(class)这些方法,这些方法是使用自定义注解的主要方法,例如:
public static void main( String[] args ) throws Exception
{
Class<AnnotatedClass> object = AnnotatedClass.class;
// Retrieve all annotations from the class
Annotation[] annotations = object.getAnnotations();
for( Annotation annotation : annotations )
{
System.out.println( annotation );
}
// Checks if an annotation is present
if( object.isAnnotationPresent( CustomAnnotationClass.class ) )
{
// Gets the desired annotation
Annotation annotation = object.getAnnotation( CustomAnnotationClass.class );
System.out.println( annotation );
}
// the same for all methods of the class
for( Method method : object.getDeclaredMethods() )
{
if( method.isAnnotationPresent( CustomAnnotationMethod.class ) )
{
Annotation annotation = method.getAnnotation( CustomAnnotationMethod.class );
System.out.println( annotation );
}
}
}
运行后输出如下:
@com.danibuiza.javacodegeeks.customannotations.CustomAnnotationClass(getInfo=Info, author=danibuiza, date=2014-05-05)
@com.danibuiza.javacodegeeks.customannotations.CustomAnnotationClass(getInfo=Info, author=danibuiza, date=2014-05-05)
@com.danibuiza.javacodegeeks.customannotations.CustomAnnotationMethod(author=friend of mine, date=2014-06-05, description=annotated method)
@com.danibuiza.javacodegeeks.customannotations.CustomAnnotationMethod(author=danibuiza, date=2014-06-05, description=annotated method)
如果使用@Inherited修饰注解,那么子类是可以继承父类的注解的,但是这仅仅对于继承类的时候才有用,如果是实现接口,那么继承不再有效,例如:
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface InheritedAnnotation
{
}
@InheritedAnnotation
public class AnnotatedSuperClass
{
public void oneMethod()
{
}
}
public class AnnotatedSubClass extends AnnotatedSuperClass
{
@Override
public void oneMethod(){
}
}
System.out.println( "is true: " + AnnotatedSuperClass.class.isAnnotationPresent( InheritedAnnotation.class ) );
System.out.println( "is true: " + AnnotatedSubClass.class.isAnnotationPresent( InheritedAnnotation.class ) );
输出:
is true: true
is true: true
而对于实现接口:
@InheritedAnnotation
public interface AnnotatedInterface
{
public void oneMethod();
}
public class AnnotatedImplementedClass implements AnnotatedInterface
{
@Override
public void oneMethod()
{
}
}
System.out.println( "is true: " + AnnotatedInterface.class.isAnnotationPresent( InheritedAnnotation.class ) );
System.out.println( "is true: " + AnnotatedImplementedClass.class.isAnnotationPresent( InheritedAnnotation.class ) );
输出如下:
is true: true
is true: false