androidJava 深入理解程序员

Java注解

2016-02-20  本文已影响289人  接地气的二呆

title: Java注解
date: February 1, 2016 3:12 PM
categories: java
tags: [注解,java]


[TOC]
我的博客

注解

注解目的

  1. 生成文档 ,如 @see @param @return 等
  2. 跟踪代码依赖性,实现替代配置文件功能
  3. 在编译时进行格式检查。如@override

注解基础

最基础的注解如下

@Entity

@ 表示这是一个注解,之后的字母表示这个注解的名字,以上例子的注解名字为 Entity

注解元素

Java 注解中有一些元素,并且可以设置他们的值,举个🌰

@Entity(tableName = "vehicles")

注解Entity中含有一个tableName元素,并且把这个元素赋值为vehicles。

一个注解也可以同时含有多个元素

@Entity(tableName = "vehicles", primaryKey = "id")

当一个注解只含有一个元素时,赋值可以写成以下形式

@InsertNew("yes")

注解的种类

注解可以修饰 类、接口、方法、参数、域、本地变量。

@Entity
public class Vehicle {

    @Persistent
    protected String vehicleName = null;


    @Getter
    public String getVehicleName() {
        return this.vehicleName;
    }

    public void setVehicleName(@Optional vehicleName) {
        this.vehicleName = vehicleName;
    }

    public List addVehicleNameToList(List names) {

        @Optional
        List localNames = names;

        if(localNames == null) {
            localNames = new ArrayList();
        }
        localNames.add(getVehicleName());

        return localNames;
    }

}

Java 内置的注解

Java 内置了三种指导编译的注解,分别为

@Deprecated

Annotation type used to mark program elements that should no longer be used by programmers. Compilers produce a warning if a deprecated program element is used.

可以修饰 类、方法、域。表示之后不会被使用了。如果代码中使用到了注解为@Deprecated 的代码,编译器会产生警告

@Override

Annotation type used to mark methods that override a method declaration in a superclass. Compilers produce an error if a method annotated with @Override does not actually override a method in a superclass.

修饰方法,表示此方法复现了父类的方法,如果在父类中没有相应的方法编译器会报错

@Override 并不是必须的,但是在子类中复写父类的方法中最好使用,以防复写的时候名字和父类的方法名不一致而产生一些问题

public class MySuperClass {

    public void doTheThing() {
        System.out.println("Do the thing");
    }
}


public class MySubClass extends MySuperClass{

    @Override
    public void doTheThing() {
        System.out.println("Do it differently");
    }
}

@SuppressWarnings

Annotation type used to indicate that the compiler should not issue the specified warnings for the marked program element. Warnings are not only suppressed for the annotated element but also for all program elements contained in that element.

It is recommended that programmers always use this annotation on the most deeply nested element where it is actually needed.

使编译器不产生对此方法的警告信息。

自定义注解

注解的定义和类、接口的定义类似。举个🌰

@interface MyAnnotation {
    String   value();
    String   name();
    int      age();
    String[] newNames();
}

使用 @interface 关键字表示定义的是一个注解。其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。,元素只支持原始的数据类型。
使用上述的注解

@MyAnnotation(
    value="123",
    name="Jakob",
    age=37,
    newNames={"Jenkov", "Peterson"}
)
public class MyClass {

}

元素默认值

在定义注解时可以设置默认值,举个🌰

@interface MyAnnotation {
    String   value() default "";
    String   name();
    int      age();
    String[] newNames();
}

元素value在使用时可以不赋值,当不赋值时,默认采用定义时的默认值

@MyAnnotation(
    name="Jakob",
    age=37,
    newNames={"Jenkov", "Peterson"}
)
public class MyClass {

}

@Retention

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

@Retention(RetentionPolicy.RUNTIME)

@interface MyAnnotation {

    String   value() default "";

}

使用时可以使用反射的方法得到注解中的信息

反射得到注解信息

类注解

@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass {
}


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnotation {
    public String name();
    public String value();
}

//法1:可以直接得到所有的注解,在里面寻找MyAnnotation
Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}


//法2:可以直接得到MyAnnotation注解
Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
方法注解
public class TheClass {
  @MyAnnotation(name="someName",  value = "Hello World")
  public void doSomething(){}
}

Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotation) annotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

//同样
Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotation) annotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}
域、参数注解同理

@Target

用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。

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

@Target({ElementType.METHOD})
public @interface MyAnnotation {

    String   value();
}

🌰表示这个注解只能修饰方法

表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括:

@Inherited

允许子类继承父类中的注解,举个🌰

java.lang.annotation.Inherited

@Inherited
public @interface MyAnnotation {

}
@MyAnnotation
public class MySuperClass { ... }
public class MySubClass extends MySuperClass {... }

在这个例子中,因为MySubClass继承了MySuperClass,并且MySuperClass被注解@MyAnnotation修饰了,所以类MySubClass继承了@MyAnnotation注解

@Documented

@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。
举个🌰

import java.lang.annotation.Documented;

@Documented
public @interface MyAnnotation {

}
@MyAnnotation
public class MySuperClass { ... }

参考

http://blog.csdn.net/tigerdsh/article/details/8848890
http://tutorials.jenkov.com/java/annotations.html

上一篇下一篇

猜你喜欢

热点阅读