1、什么是java注解
Annotation(注解)是JDK5.0及以后版本引入的一个特性。注解是java的一个新的类型(与接口很相似),它与类、接口、枚举是在同一个层次,它们都称作为java的一个类型(TYPE)。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。它的作用非常的多,例如:进行编译检查、生成说明文档、代码分析等。
2.jdk提供的3个基本注解
@SuppressWarnings
该注解的作用是阻止编译器发出某些警告信息。它可以有以下参数:
deprecation:过时的类或方法警告。
unchecked:执行了未检查的转换时警告。
fallthrough:当Switch程序块直接通往下一种情况而没有Break时的警告。path:在类路径、源文件路径等中有不存在的路径时的警告。serial:当在可序列化的类上缺少serialVersionUID定义时的警告。finally:任何finally子句不能完成时的警告。all:关于以上所有情况的警告。
@Deprecated
该注解的作用是标记某个过时的类或方法。
c.
@Override
该注解用在方法前面,用来标识该方法是重写父类的某个方法。
3.注解的生命周期
一个注解可以有三个生命周期,它默认的生命周期是保留在一个CLASS文件,但它也可以由一个@Retetion的元注解指定它的生命周期。
a.java源文件
当在一个注解类前定义了一个@Retetion(RetentionPolicy.SOURCE)的注解,那么说明该注解只保留在一个源文件当中,当编译器将源文件编译成class文件时,它不会将源文件中定义的注解保留在class文件中。
b.class文件中
当在一个注解类前定义了一个@Retetion(RetentionPolicy.CLASS)的注解,那么说明该注解只保留在一个class文件当中,当加载class文件到内存时,虚拟机会将注解去掉,从而在程序中不能访问。
c.程序运行期间
当在一个注解类前定义了一个@Retetion(RetentionPolicy.RUNTIME)的注解,那么说明该注解在程序运行期间都会存在内存当中。此时,我们可以通过反射来获得定义在某个类上的所有注解。
4.元注解
元注解,就是定义注解的注解,也就是说这些元注解是的作用就是专门用来约束其它注解的注解。请区别上面那三个注解,他们也是通过元注解定义而来的。
元注解有哪些呢,主要有四个@Target,@Retention,@Documented,@Inherited
5.自定义注解
package com.ljq.test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 定义一个注解
*
*
* @author jiqinlin
*
*/
//Java中提供了四种元注解,专门负责注解其他的注解,分别如下
//@Retention元注解,表示需要在什么级别保存该注释信息(生命周期)。可选的RetentionPoicy参数包括:
//RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉
//RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认)
//RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注解的信息
//@Target元注解,默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括
//ElementType.CONSTRUCTOR: 构造器声明
//ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
//ElementType.LOCAL_VARIABLE: 局部变量声明
//ElementType.METHOD: 方法声明
//ElementType.PACKAGE: 包声明
//ElementType.PARAMETER: 参数声明<pre class="java" name="code">//ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。
//ElementType.TYPE: 类、接口(包括注解类型)或enum声明 //@Documented将注解包含在JavaDoc中 //@Inheried允许子类继承父类中的注解 @Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE}) public @interface MyAnnotation { //为注解添加属性 String color(); String value() default "我是林计钦"; //为属性提供默认值 int[] array() default {1, 2, 3}; Gender gender() default Gender.MAN; //添加一个枚举 MetaAnnotation metaAnnotation() default @MetaAnnotation(birthday="我的出身日期为1988-2-18"); //添加枚举属性 }
package com.ljq.test;
/**
* 注解测试类
*
*
* @author jiqinlin
*
*/
//调用注解并赋值
@MyAnnotation(metaAnnotation=@MetaAnnotation(birthday = "我的出身日期为1988-2-18"),color="red", array={23, 26})
public class AnnotationTest {
public static void main(String[] args) {
//检查类AnnotationTest是否含有@MyAnnotation注解
if(AnnotationTest.class.isAnnotationPresent(MyAnnotation.class)){
//若存在就获取注解
MyAnnotation annotation=(MyAnnotation)AnnotationTest.class.getAnnotation(MyAnnotation.class);
System.out.println(annotation);
//获取注解属性
System.out.println(annotation.color());
System.out.println(annotation.value());
//数组
int[] arrs=annotation.array();
for(int arr:arrs){
System.out.println(arr);
}
//枚举
Gender gender=annotation.gender();
System.out.println("性别为:"+gender);
//获取注解属性
MetaAnnotation meta=annotation.metaAnnotation();
System.out.println(meta.birthday());
}
}
}
package com.ljq.test;
/**
* 枚举,模拟注解中添加枚举属性
*
* @author jiqinlin
*
*/
public enum Gender {
MAN{
public String getName(){return "男";}
},
WOMEN{
public String getName(){return "女";}
}; //记得有“;”
public abstract String getName();
}
package com.ljq.test;
/**
* 定义一个注解,模拟注解中添加注解属性
*
* @author jiqinlin
*
*/
public @interface MetaAnnotation {
String birthday();
}
本文部分内容来自 http://www.cnblogs.com/linjiqin/archive/2011/02/16/1956426.html 为了学习本人收藏,并有些改动
jdk8新特性 重复注解
package com.javacodegeeks.java8.repeatable.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class RepeatingAnnotations {
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
public @interface Filters {
Filter[] value();
}
@Target( ElementType.TYPE )
@Retention( RetentionPolicy.RUNTIME )
@Repeatable( Filters.class )
public @interface Filter {
String value();
};
@Filter( "filter1" )
@Filter( "filter2" )
public interface Filterable {
}
public static void main(String[] args) {
for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) {
System.out.println( filter.value() );
}
}
}
正如我们看到的,这里有个使用@Repeatable( Filters.class )注解的注解类Filter,Filters仅仅是Filter注解的数组,但Java编译器并不想让程序员意识到Filters的存在。这样,接口Filterable就拥有了两次Filter(并没有提到Filter)注解。
同时,反射相关的API提供了新的函数getAnnotationsByType()来返回重复注解的类型(请注意Filterable.class.getAnnotation( Filters.class )经编译器处理后将会返回Filters的实例)。
程序输出结果如下:
filter1 filter2 |