欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中注解(Annatation)的使用 博客分类: java基础 java注释注解重复注解Annotation 

程序员文章站 2024-03-24 20:51:34
...

目录

1.元注解

2.注解的声明

3.注解的使用

4.重复注解

 

java提供了一套java注解(Annotation)的机制,与java中的注释不同,注解是一种类型.通过使用注解,可以对方法,类,参数,包,域以及变量等添加标记(即附上某些信息),之后通过反射将标记的信息提取出来以供使用.

 
1.元注解

 

java.lang.annotation包提供了4种元注解,负责对注解类型进行约束,他们本身也实现了自注解.

@Target:表示该注解用于什么位置,可选的参数是ElementType枚举中的成员:

TYPE 类型声明(类,接口,enum)
FIELD 成员变量声明(对象,属性,enum的实例)
METHOD 方法声明
PARAMETER 参数声明
CONSTRUCTOR 构造器声明
LOCAL_VARIABLE 局部变量声明
ANNOTATION_TYPE 注解声明
PACKAGE

包声明

ElementType在SE1.8中又加入了两个成员:TYPE_PARAMETER,TYPE_USE.

 

@Retention:表示需要在什么级别保存该注解信息(生命周期),可选的参数是RetentionPolicy枚举中的成员:

SOURCE 停留在java源文件,会将被编译器丢弃
CLASS 停留在class文件中,但会被VM丢弃
RUNTIME 内存中的字节码,VM在运行期间保留注解

注意,只有声明为RUNTIME,才可以通过反射机制读取注解的信息.


@Document:将注解包含在Javadoc中

@Inherited:允许子类继承父类中的注解,只针对CLASS级别的注解有效

 

2.注解的声明

 

语法:通过关键字@interface定义,默认继承Annotation接口.注解中通常会有一些元素(),用来表示一些值.这些元素看起来与接口中的方法相似,但是是无参的,并且可以通过default提供默认值,但默认值不能为null.注解中的元素只能是以下类型{所有基本类型,String,Class,Enum,Annotation(但不能是自己),以及以上类型的一维数组形式}.例:

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotateDemo {

	int i();

	float f() default 3.14f;

	char[] c();

	String[] s() default { "primitive type", "String", "Class", "annotation",
			"enumeration", "arrays" };

	Class<String> cls() default String.class;

	Override ovr();

	ElementType elmt();

}

注解可以不用元注解进行约束,也可以没有元素,没有元素的注解称为标记注解,例:

public @interface AnnotateDemo {

}

默认的ElementType可以是任意类型,RetentionPolicy是CLASS.

 

3.注解的使用

 

当我们定义了一个注解之后,便可以在允许的位置进行标记,标记时必须对注解内的元素进行赋值,有默认值的元素可以选择性赋值.如果注解只有一个元素且该元素的名称是value的话,在使用注解的时候可以省略"value="直接写需要的值即可.例:

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

@Retention(RetentionPolicy.RUNTIME)
@interface AnnotateDemo {

	int i();
	String s() default "hello";

}

public class AnnotateDemo3 {

	@AnnotateDemo(i = 97)
	public void a() {

	}

	@AnnotateDemo(i = 98, s = "world")
	public void b() {

	}

	public void c() {

	}

	public void d() {

	}

}

使用注解最主要的部分在于对注解的处理,那么就会涉及到注解处理器.注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理.在上述程序中加入:

	public static void track(List<Integer> list, Class<?> cl) {

		for (Method m : cl.getDeclaredMethods()) {
			AnnotateDemo ant = m.getAnnotation(AnnotateDemo.class);
			if (ant != null) {
				System.out.println("Found:" + ant.i() + "_" + ant.s());
				list.remove(new Integer(ant.i()));
			}
		}
		for (int value : list) {
			System.out.println("notFound:" + value);
		}
	}

	public static void main(String[] args) {
		List<Integer> list = new ArrayList<>();
		Collections.addAll(list, 97, 98, 99, 100);
		track(list, AnnotateDemo3.class);
	}

静态方法track需要List和Class的参数,遍历cl中的方法,通过getAnnotation()方法,判断cl中的方法是否被标记.如果是,则输出注解的详细信息,然后在list中remove掉对应的值,最后再输出list中剩下的值.输出结果:
Found:97_hello
Found:98_world
notFound:99
notFound:100
这也是一个简单的跟踪项目中的例子.

 

4.重复注解


SE1.8引入了重复注解的特性,允许在声明同一类型时使用多次同一个注解,提高了程序的可读性,例:

import java.lang.annotation.Repeatable;

@Repeatable(AnnotateDemoFactory.class)
@interface AnnotateDemo {
	String s();
}

@interface AnnotateDemoFactory {
	AnnotateDemo[] value();
}

public class AnnotateDemo4 {

	@AnnotateDemo(s = "hello")
	@AnnotateDemo(s = "world")
	public void a() {

	}
}


通过使用另一个注解来存储重复注解,创建重复注解AnnotateDemo时,加上@Repeatable,指向存储注解AnnotateDemoFactory.在使用时可以重复使用AnnotateDemo来进行标记.

 

小结:了解java中注解的用法需要对反射有一定了解,通过使用注解可以实现生成文档,编译检查等功能,同时增加了程序的可读性.