Java注解
来源:互联网 发布:c语言英语怎么说 编辑:程序博客网 时间:2024/06/11 23:26
原文链接: http://swiftlet.net/archives/1906
第一节:注解的作用
Annotation(注解)是JDK5.0及以后版本引入的。它的作用是修饰编程元素。什么是编程元素呢?例如:包、类、构造方法、方法、成员变量等。
第二节:注解的作者
注解是JDK 5.0推出来的,这部分JDK源码的作者是:Joshua Bloch,这是一个技术大牛。Collections Framework皆是他一手打造,还获得了当年的Jolt大奖。另外,他还写了一本非常出名的书:《Effective Java》,相信大家不会陌生吧。如果没有读过这本书,那到这里下载下来看看吧:http://swiftlet.net/archives/495。关于更多Joshua Bloch的故事,后期金丝燕网将会单独撰文介绍,这里不再赘述了。
第三节:注解的语法与定义形式
(1)以@interface关键字定义
(2)注解包含成员,成员以无参数的方法的形式被声明。其方法名和返回值定义了该成员的名字和类型。
(3)成员赋值是通过@Annotation(name=value)的形式。
(4)注解需要标明注解的生命周期,注解的修饰目标等信息,这些信息是通过元注解实现。
上面的语法不容易理解,下面通过例子来说明一下,这个例子就是Target注解的源码,
源码分析如下:
第一:元注解@Retention,成员value的值为RetentionPolicy.RUNTIME。
第二:元注解@Target,成员value是个数组,用{}形式赋值,值为ElementType.ANNOTATION_TYPE
第三:成员名称为value,类型为ElementType[]
另外,需要注意一下,如果成员名称是value,在赋值过程中可以简写。如果成员类型为数组,但是只赋值一个元素,则也可以简写。如上面的简写形式为:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
第四节:注解的分类
注解分为两类,一类是元注解,另外一类是普通注解。
所谓元注解就是修饰注解的注解。
拿到一个注解,如何知道它是否是元注解呢?需要看它的元注解(无论是元注解还是普通注解都是有元注解的),如果看到这样的元注解:@Target(ElementType.ANNOTATION_TYPE),那么此时这个注解一定是元注解。
第五节:注解的生命周期
注解的定义语法中已经说到了:注解需要标明注解的生命周期,这些信息是通过元注解实现。而这个元注解是:
Retention注解的值是enum类型的RetentionPolicy。包括如下几种情况:
(1)SOURCE: 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃。Annotations are to be discarded by the compiler.
(2)CLASS: 注解被保留到class文件,jvm加载class文件时候被遗弃。这是默认的生命周期。
Annotations are to be recorded in the class file by the compiler
but need not be retained by the VM at run time. This is the default
behavior.
(3)RUNTIME: 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在,保存到class对象中,可以通过反射来获取。
Annotations are to be recorded in the class file by the compiler and
retained by the VM at run time, so they may be read reflectively.
第六节:注解的修饰目标
注解的定义语法中已经说到了:注解需要标明注解的修饰目标,这些信息是通过元注解实现。而这个元注解是:
这个注解的值是enum类型ElementType。包括以下几种情况:
(1)TYPE:指的是在类,接口(包括注解)或者enum上使用的注解。
(2)FIELD:指的在field属性,也包括enum常量使用的注解。
(3)METHOD:指的是在方法声明上使用的注解。
(4)PARAMETER:指的是在参数上使用的注解,
(5)CONSTRUCTOR: 指的是在构造器使用的注解。
(6)LOCAL_VARIABLE:指的是在局部变量上使用的注解。
(7)ANNOTATION_TYPE:指的是在注解上使用的元注解
(8)PACKAGE:指的是在包上使用的注解。
第七节:注解的底层实现
定义一个注解:
分析其字节码,如下图所示:
C:\Users\Administrator\workspace\cache\bin>javap -verbose Cache
分析上面的字节码,我们可以得出:
第一:
public interface Cache extends java.lang.annotation.Annotation,说明Cache注解是继承自Annotation,仍然是interface。
第二:
public abstract java.lang.String value(),说明value方法是abstract类型。
注解的作用:
1、生成文档。这是最常见的,也是java 最早提供的注解。常用的有@see @param @return 等
2、跟踪代码依赖性,实现替代配置文件功能。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量。以后java的程序开发,最多的也将实现注解配置,具有很大用处;
3、在编译时进行格式检查。如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
使用方法详解:
下面是注解类,其实注解也就是一个类文件
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import entity.PersonChiness;
/***
* Retention:保持、保留
* RetentionPolicy:政策、方针
* @author huawei
*@Retention
*1、指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS
*2、有三种取值(代表三个阶段):
* RetentionPolicy.SOURCE:保留注解到java源文件阶段,例如Override、SuppressWarnings
* RetentionPolicy.CLASS:保留注解到class文件阶段,例如
* RetentionPolicy.RUNTIME:保留注解到运行时阶段即内存中的字节码,例如Deprecated
*/
//元注解:表示的是注解的注解,(同义词有元信息、元数据)
//如果不加,javac会把这无用的注解丢掉
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})//指定该注解使用的用处:用在class上和用在方法体上。
public @interface HelloAnnotation {
//返回值是String类型
String color() default "蓝色";//方法,但是相当于注解的属性,即:当成属性赋值,当成方法调用。
//默认value
String value();
String author() default "默认给定了属性";
//返回值是数组对象
int[] arrayAttr() default {1};
//返回值是注解类型
MetaAnnotation annotationAttr() default @MetaAnnotation("");
//返回CLASS对象
Class<PersonChiness> classType() default PersonChiness.class;
}
下面是实现注解的测试类:
package annotation;
/***
* 注解类:
* 1、相当于一种标记,加上注解就等于为程序打上了某种标记,没加,则等于没加某种标记,
* 2、以后javac编译器、开发工具或其他应用程序可以通过反射来了解你的类,以及各种元素上有无何种标记,
* 看你有什么标记,就去执行相应的命令和干相应的事。
* 3、标记用处地方:
* 加在包、类、字段、方法、方法的参数、局部变量
* @author huawei
*
*/
//自定义注解
@HelloAnnotation(color="红色",
value="如果只有value属性!可以不写属性名和等于号,直接写值即可!",
arrayAttr={1,2,3},
annotationAttr=@MetaAnnotation("返回注解类型规范形式。"))
public class AnnotationTest {
@SuppressWarnings("deprecation")//阻止警告
@HelloAnnotation("当为value属性时,可以省掉属性名和等于号。")
public static void main(String[] args) throws Exception{
System.runFinalizersOnExit(true);
if(AnnotationTest.class.isAnnotationPresent(HelloAnnotation.class)){
HelloAnnotation helloAnnotation =
(HelloAnnotation)AnnotationTest.class.getAnnotation(HelloAnnotation.class);
System.out.println("color(): "+helloAnnotation.color());
System.out.println("value(): "+helloAnnotation.value());
System.out.println("author(): "+helloAnnotation.author());
System.out.println("arrayAttr(): "+helloAnnotation.arrayAttr().length);
System.out.println("annotationAttr(): "+helloAnnotation.annotationAttr().value());
System.out.println("classType(): "+helloAnnotation.classType().newInstance().sayHello("hello,ketty"));
}
}
@Deprecated//自定义:备注过时的方法信息
public static void sayHello(){
System.out.println("hello,world");
}
}
- Java注解-自定义注解
- Java注解----自定义注解
- Java注解自定义注解
- Java注解--四种元注解
- Java注解-三种內建注解
- 【Java】【注解】自定义注解
- java注解
- java注解
- java注解
- java 注解
- Java注解
- java 注解
- Java 注解
- Java注解
- java 注解
- JAVA注解
- Java注解
- Java注解
- PHP_7.0_升级备注
- yahoo鉴黄模型测试
- PowerDesigner15.1创建模型及生成带注释sql
- hihoCoder 1051 : 补提交卡(贪心+枚举)
- 通过Flume拉取Kafka数据保存到HDFS
- Java注解
- [JAVA学习笔记-85]java的concurrent包的整体认识
- ServletContext与ApplicationContext
- 数据库存储过程学习(一)
- 学习笔记——JAVA执行javascript
- AngularJs的UI组件ui-Bootstrap分享(四)——Datepicker Popup
- Oracle 11G数据库导入导出
- 使用Openssl 创建可以被Torando使用的crt证书以及Key密钥
- [JAVA学习笔记-86]ConcurrentHashMap与synchronizedMap的对比