定义:注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

注解(Annotation)为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后某个时刻方便地使用这些数据(通过 解析注解 来使用这些数据),常见的作用有以下几种:

  • 生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
  • 跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。
  • 在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。

java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。

如接口 java.lang.annotation.Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。

java.lang包中预定义了三个注解   Override、Deprecated和SuppressWarnings

Override表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。

//重写hashCode()方法
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((str1 == null) ? 0 : str1.hashCode());
		result = prime * result + ((str2 == null) ? 0 : str2.hashCode());
		result = prime * result + ((str3 == null) ? 0 : str3.hashCode());
		result = prime * result + x;
		result = prime * result + y;
		return result;
	}

Deprecated用 @Deprecated 注释的程序元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。

这个注解是一个标记注解。所谓标记注解,就是在源程序中加入这个标记后,并不影响程序的编译,但有时编译器会显示一些警告信息。

anroid studio java工程引入_元注解

如果某个类成员的提示中出现了个词,就表示这个并不建议使用这个类成员。因为这个类成员在未来的JDK版本中可能被删除。之所以在现在还保留,是因为给那些已经使用了这些类成员的程序一个缓冲期。如果现在就去了,那么这些程序就无法在新的编译器中编译了。

SuppressWarnings与Deprecated 相对,即然有使编译器产生警告信息的,那么就有抑制编译器产生警告信息的。

@SuppressWarnings(value={"unchecked"})
	public static void method2()
	{
		//默认警告信息表示List类必须使用范型才是安全的。
		//如果想不显示这个警告信息则可以通过@SuppressWarnings注解取消警告。
		ArrayList ar=new ArrayList();
		ar.add("234");
	}

作用:指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。

@SuppressWarnings("deprecation")
	public static void main(String[] args) {
		System.runFinalizersOnExit(true);		
	}

注意;SuppressWarnings和前两个注解不一样,这个注解有一个属性。

当然,还可以抑制其它警告,如@SuppressWarnings(value={"unchecked", "fallthrough"})

根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。

自定义注解

注解的强大之处是它不仅可以使java程序变成自描述的,而且允许程序员自定义注解。

anroid studio java工程引入_java_02

注解的定义和接口差不多,只是在interface前面多了一个“@”。

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

/*
 *@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。
 *方法的名称就是参数的名称,返回值类型就是参数的类型。
 *可以通过default来声明参数的默认值。
 *在这里可以看到@Retention和@Target这样的元注解,用来声明注解本身的行为。
 *@Retention用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种, 
 	分别表示注解保存在类文件、JVM运行时刻和源代码中。
 	分别对应:class文件-->内存中的字节码-->java源文件。
 *只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。 
 *@Target用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。
 *就可以定义一个注解了,它将自动继承Annotation */
//元注解  (元数据  元信息)  
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})  //class其中一个实现TYPE接口
public @interface Test {
	//自定义了一个注解类
}

把注解加在某个类上:

@Test
public class AppTest {
	public static void main(String[] args) {
		//对 “应用了注解类的类” 进行反射操作的类
		System.out.println(AppTest.class.isAnnotationPresent(Test.class));
	}
}

元注解:注解的注解

四个元注解分别是:@Target,@Retention,@Documented,@Inherited,再次强调下元注解是java API提供,是专门用来定义注解的注解,其作用分别如下。

@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,包括: 
  ElemenetType.CONSTRUCTOR 构造器声明 
  ElemenetType.FIELD 域声明(包括 enum 实例) 
  ElemenetType.LOCAL_VARIABLE 局部变量声明 
  ElemenetType.METHOD 方法声明 
  ElemenetType.PACKAGE 包声明 
  ElemenetType.PARAMETER 参数声明 
  ElemenetType.TYPE 类,接口(包括注解类型)或enum声明 
   
@Retention 表示在什么级别保存该注解信息。可选的参数值在枚举类型 RetentionPolicy 中,包括: 
  RetentionPolicy.SOURCE 注解将被编译器丢弃 
  RetentionPolicy.CLASS 注解在class文件中可用,但会被VM丢弃 
  RetentionPolicy.RUNTIME VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。 
   
@Documented 将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。

@Inherited 允许子类继承父类中的注解,例子中补充。