1、Annotation简介
简介
1、Annotation是java5开始引入的新特性,中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据与程序元素(类、方法、成员变量、局部变量 ...)进行关联
2、更通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息与程序的业务逻辑无关,并且提供指定的工具或框架使用的
3、Annotation像一种修饰符一样,应用于包、类、构造方法、方法、成员变量、参数及本地变量的声明语句中
原理
1、Annotation其实是一种接口。通过Java的反射机制相关的API来访问annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。
2、annotation是不会影响程序代码的执行,无论annotation怎么变化,代码都始终如一地执行。
3、Java语言解释器在工作时会忽略这些annotation,因此在JVM 中这些annotation是“不起作用”的,只能通过配套的工具才能对这些annontaion类型的信息进行访问和处理。annotation的工具统称apt(Annotation processing tool)
2、常见的标准Annotation
@Override
@Override就是用来指定方法重写的,它可以强调一个子类必须要覆盖父类的方法
class Fruit{
public void info() {
System.out.println("描述水果信息");
}
}
class Apple extends Fruit{
@Override
public void info() {
super.info();
System.out.println("我是苹果");
}
}
public class Demo1 {
public static void main(String[] args) {
Fruit fruit = new Apple();
fruit.info();
}
}
@Deprecated
@Deprecated用于表示某个程序元素(类、方法等)已过时,当其它程序使已过时的类、方法时,编译器将会给出警告
class Person{
@Deprecated
public void showInfo() {
System.out.println("hello person");
}
}
public class Demo2 {
public static void main(String[] args) {
Person person = new Person();
person.showInfo();
}
}
@SuppressWarnings
@SuppressWarnings指示被Annotation标识的程序元素(以及在该程序元素中的所有子元素)取消显示指定的编译警告
class Container<T>{
private Object[] obj = null;
public Container() {
obj = new Object[10];
}
@SuppressWarnings("unchecked")
public T[] toArr() {
return (T[])obj;
}
}
3、自定义Annotation
1、语法:
访问修饰符 @interface Annotation 名称{
返回类型 method1() [default 默认值]
}
2、特点:
1、Annotation类型使用关键字@interface而不是interface
2、Annotation类型方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员:方法名成为了成员名,而方法返回值成为了成员的类型
3、方法返回值类型必须为基本类型、String类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组
4、方法的后面可以使用default和一个默认数值来声明成员的默认值,null不能作为成员默认值
5、在定义Annotation型态时,不能继承其它的Annotation型态或是接口
//标记注解 可以修饰类的任何成员
@interface MyAnnotation1{
}
public class MyAnnotation {
@MyAnnotation1
public static void main(String[] args) {
}
}
@MyAnnotation1
public class MyAnnotation {
public static void main(String[] args) {
}
}
public class MyAnnotation {
@MyAnnotation1
private String name;
public static void main(String[] args) {
}
}
@interface MyAnnotation2{
String name();
}
public class MyAnnotation {
@MyAnnotation2(name="张三")//name必须写~如果是value就可以省略
public static void main(String[] args) {
}
}
@interface MyAnnotation3{
String value();
}
public class MyAnnotation {
@MyAnnotation3("张三")
public static void main(String[] args) {
}
}
@interface MyAnnotation4{
String value() default "张撒";
int age();
}
public class MyAnnotation {
@MyAnnotation4(value="张三",age=12)
public static void main(String[] args) {
}
}
@interface MyAnnotation5{
String[] value();
}
public class MyAnnotation {
@MyAnnotation5({"张三","李四"})
public static void main(String[] args) {
}
}
enum Color{
Red,Blue
}
@interface MyAnnotation6{
Color value();
}
public class MyAnnotation {
@MyAnnotation6(Color.Blue)
public static void main(String[] args) {
}
}
4、Meta Annotation
1、概念:Meta Annotation也称为元Annotation,也是一种Annotation,可以对其它的Annotation进行注释
2、java5.0提供了一些标准的Meta Annotation
1、@Retention
@Retention(SOURCE/CLASS/RUNTIME)
public/default @interface Annotation名称{...}
SOURCE:Annotation信息在编译阶段被丢弃,仅保留在java源文件中
CLASS(默认):Annotation信息在编译阶段被保留,保留到class文件当中,但是运行阶段不存在
RUNTIME:Annoation信息一直保留到运行阶段,直到退出虚拟机才被丢弃
以上三个值是java.lang.annotation.Retention这个类所提供的枚举值。作用:控制被Retention注释的Annotation信息保留时间长短
2、@Target
@Target({ElementType.METHOD,ElementType.TYPE})
public/default @interface Annotation名称{...}
@Target(ElementType.TYPE) //接口、类
@Target(ElementType.FIELD)//字段、枚举的常量
@Target(ElementType.METHOD)//方法
@Target(ElementType.PARAMETER)//参数
@Target(ElementType.CONSTRUCTOR)//构造函数
@Target(ElementType.LOCAL_VARIABLE)//局部变量
@Target(ElementType.ANNOTATION_TYPE)//注解
@Target(ElementType.PACKAGE) //包
3、@Documented
@Documented
public/default @interface Annotation名称{...}
//生成java Doc 的时候会包含注解信息
4、@Inherited
@Inherited
public/default @interface Annotation名称{...}
//标识性注解,容许子注解进行继承
5、反射与Annotation
一个Annotation真正起作用,必须结合反射机制,在java.lang.reflect反射包中提供AccessibleObject类来对Annotation进行操作,最常用的方法如下:
//判断是否使用指定的Anotation
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
//得到所有的Annotation
public Annotation[] getAnnotations()
通过反射获取类注解信息
package com.note.reflection2;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@interface Auther{
String name();
String group();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@interface Description{
String value();
}
@Description("这是一个用来测试的类")
class AnnotationTest {
@Auther(name="张三",group="com.im")
public void test() {
System.out.println("test -----------------");
}
}
public class Demo2 {
/***
* 通过反射获取类注解信息
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Class<?> cc = Class.forName("com.note.reflection2.AnnotationTest");
if(cc.isAnnotationPresent(Description.class)) {
Description description = cc.getAnnotation(Description.class);
System.out.println("Description's Description->" + description.value());
Method[] methods = cc.getMethods();
for(Method method : methods) {
if(method.isAnnotationPresent(Auther.class)) {
Auther auther = method.getAnnotation(Auther.class);
System.out.println("Auther-->" + auther.name() + " " + auther.group());
}
}
}
}
}
运行结果:
Description's Description->这是一个用来测试的类
Auther-->张三 com.im