一、注解的作用:
1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处;
3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
二、注解的作用范围:
@Retention
CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。
RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。
SOURCE
编译器要丢弃的注释。
@Retention注解可以在定义注解时为编译程序提供注解的保留策略。属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。
@Target
ANNOTATION_TYPE
注释类型声明
CONSTRUCTOR
构造方法声明
FIELD
字段声明(包括枚举常量)
LOCAL_VARIABLE
局部变量声明
METHOD
方法声明
PACKAGE
包声明
PARAMETER
参数声明
TYPE(类、接口(包括注释类型)或枚举声明)
@Documented
要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。
@Inherited
在注解中使用继承:默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。
例1:
@Target(ElementType.TYPE)//注解可以在什么地方使用
@Retention(RetentionPolicy.RUNTIME)//表示在什么级别保存注解信息 Source注解将被编译器丢弃 class注解在class文件可用。被VM丢弃
//vm运行期保存 通过反射机制可以获取
@Documented //将注解包含在javadoc中
@Inherited //允许子类继承父类的注解
public @interface A {
public int a1() default 0;
public float a2();
public boolean a3() default true;
public String a4() default "";
public MyEnum a5() default MyEnum.Rainy;
public B a6() default @B;
//包括基本类型和String enum annotation
}
enum MyEnum{
Suny,Rainy
}
注解的使用(简单模拟activity setContentView和findById)
Layout
package com.huang.annotation.android;
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 Layout {
int value() default 0;
}
Id
package com.huang.annotation.android;
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 Id {
int value() default 0;
}
BaseActvity
package com.huang.annotation.android;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class BaseActivity {
@Layout(100)
private View inflateView;
@Id(80)
private View myView1;
@Id(70)
private View myView2;
@Id(60)
private View myView3;
protected void onCreate() {
onPreCreate();
};
private void onPreCreate() {
Layout l = null;
List<Id> ids = new ArrayList<Id>();
Field[] fs = this.getClass().getDeclaredFields();//通过反射获取成员变量
for (int i = 0; i < fs.length; i++) {
fs[i].setAccessible(true);//强制获取
if (fs[i].getAnnotation(Layout.class) != null) {//成员变量中是否有Layout注解
l = fs[i].getAnnotation(Layout.class);
} else if (fs[i].getAnnotation(Id.class) != null) {//成员变量中是否有Id注解
ids.add(fs[i].getAnnotation(Id.class));
}
}
if(l != null){
//类似于setContentView
System.out.println("layout R id"+l.value());
for(Id id:ids){
//类似于findById
System.out.println("Id R id"+id.value());
}
}
}
public static void main(String[] args) {
new BaseActivity().onCreate();
}
}
三、通过apt工具
package annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtentionInterface {
public String value();
}
package annotations;
@ExtentionInterface("IMultiplier")
public class Multiplier {
public int multiplier(int x,int y){
int total = 0;
for(int i = 0; i< x;i++){
total = add(total,y);
}
return total;
}
private int add(int x,int y){
return x + y;
}
public static void main(String[] args) {
Multiplier m = new Multiplier();
System.out.println("11*16="+m.multiplier(11, 16));
}
}
package annotations;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.MethodDeclaration;
import com.sun.mirror.declaration.ParameterDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
@SuppressWarnings("deprecation")
public class InterfaceExtractorProcessor implements AnnotationProcessor{
private final AnnotationProcessorEnvironment env;
private ArrayList<MethodDeclaration> interfaceMethods = new ArrayList<MethodDeclaration>();
public InterfaceExtractorProcessor(AnnotationProcessorEnvironment env) {
super();
this.env = env;
}
@Override
public void process() {
//从所有的class查找是否包含ExtentionInterface注解
for(TypeDeclaration t :env.getSpecifiedTypeDeclarations()){
ExtentionInterface annot = t.getAnnotation(ExtentionInterface.class);
if(annot == null){
break;
}
//如果包含该注解则查找方法是否包含public并且不为static
for(MethodDeclaration m:t.getMethods()){
if(m.getModifiers().contains(Modifier.PUBLIC)&& !(m.getModifiers().contains(Modifier.STATIC))){
interfaceMethods.add(m);
}
}
if(interfaceMethods.size()>0){
try {
//写入interface文件
PrintWriter writer = env.getFiler().createSourceFile(annot.value());
writer.println("package "+t.getPackage().getQualifiedName()+"");
writer.println("public interface "+annot.value()+"{");
for(MethodDeclaration m : interfaceMethods){
writer.print(" public ");
writer.print(m.getReturnType() +" ");
writer.print(m.getSimpleName()+" (");
int i= 0;
for(ParameterDeclaration parm :m.getParameters()){
writer.print(parm.getType()+" "+parm.getSimpleName());
if(++i < m.getParameters().size()){
writer.println(", ");
}
}
writer.println(");");
}
writer.println("}");
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
package annotations;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
//有点类似的hibernate的SessionFactory。帮助构建环境
@SuppressWarnings("deprecation")
public class InterfaceExtractorProcessFactory implements AnnotationProcessorFactory {
//构建注解处理器,给处理器加载环境
@Override
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> arg0,
AnnotationProcessorEnvironment env) {
return new InterfaceExtractorProcessor(env);
}
//返回直接处理的注解的名称的集合
@Override
public Collection<String> supportedAnnotationTypes() {
return Collections.singleton("annotations.ExtentionInterface");
}
@Override
public Collection<String> supportedOptions() {
return Collections.emptySet();
}
}