注解详解

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

  

 

posted @ 2017-12-15 17:43  jianhuazhao  阅读(419)  评论(0编辑  收藏  举报