代码编织梦想

1. 定义

annotate 英文里面注解的意思。Java annotation 又称为java 内注( 内建) 的意思。从sun 官方网站上面看到关于java 内注的定义:java 内注提供了关于代码的一些数据( 注解), 它本身不是java 代码的一部分。它不能直接影响它注释的代码的运行。java 在jdk5 之前本身提供了一些专门的注解机制( 如transient :防止序列化) 。

网上看到的另外的一些定义:Annotation 提供了一条与程序元素关联任何信息或者任何元数据(metadata )的途径。从某些方面看,annotation 就像修饰符一样被使用,并应用于包、类型、构造方法、方法、成员变量、参数、本地变量的声明中。这些信息被存储在annotation 的“name=value” 结构对中。 annotation 类型是一种接口,能够通过java 反射API 的方式提供对其信息的访问。

2. 按功能分类 Annotations

java 的内注有些是给编译器使用的,有些是运行时可调用的关于其功能的分类可参考:

Sun 官网里关于 Annotations 的分 类:

1.( 为编译起提供信息)information for the compiler :为编译器提供信息,如编译器可以用来检查错误和忽略警告。

2.( 编译时或部署时处理)Compiler-time and deployment-time processing :可以让软件工具通过处理内注信息来产生代码、xml 文件等等。

3.( 运行时处理)runtime processing( 运行时处理) :有一些特殊的内注可以在运行时进行处理。

java5 本身提供了供编译器自己使用的几个内注,先来理解下这几个内注:

Annotations Used by the Compiler:

@Deprecated : 用来告诉编译器这个方法已经被遗弃了不再维护,当有代码引用该方法时,会提示。

@Override : 用来告诉编译器,该方法重写了父类的某个方法。这个有的时候有助于查找拼写错误。如果用了才标记,但是父类却没有该方法,则会报错。

@SuppressWarnings : 用来告诉编译器忽略一些警告。@SuppressWarnings({"unchecked", "deprecation"}) 用于忽略unchecket 和deprecation 的警告。

这几个是java 内部定义好的一些内注,我们平常在编写代码时候应该都有接触到。我们也可以自己定义内注,请继续看下面的章节。

3. 语法和使用

此功能由一个定义annotation 类型的语法和一个描述annotation 声明的语法,读取annotaion 的API ,一个使用annotation 修饰的class 文件,一个annotation 处理工具(apt )组成。

3.1 格式

Annotation 类型声明于一般的接口声明极为类似,区别只在于它在interface 关键字前面使用“@” 符号。Annotation 类型可以由>=0 个的类型成员组成。Annotation 的类型成员由类型和成员方法组成,成员方法是一个空的方法,方法名即是其成员名。类型只能是primitives 、String 、Class 、enums 、annotation 和前面类型的数组。可以有默认值。 如下几个例子涵盖了基本的语法:

例子1:

packageannotation;

public@interfaceCopyright {

String value();

}

定义了一个内注,只有一个名为 value, 类型为 String 的成员。

例子2:

packageannotation;

public@interfacePreliminary {

}

定义了一个空的内注,又称为 MarkAnnotation, 标记内注, (java 的 @overide 就是一个标记内注 )

例子 3:

packageannotation;

public@interfaceannotest {

intid();

String synopsis();

String engineer()default"[unassigned]";// 默认值是 unassigned

String date()default"[unimplemented]";

}

定义了一个有多成员的内注,且有些有默认值。

例子 4:

importjava.lang.annotation.*;

/**

* Indicates that the annotated method is a test method. This annotation should

* be used only on parameterless static methods.

*/

@Retention(RetentionPolicy. RUNTIME )// 声明了这是一个运行时的內注, java 虚拟机不会抛弃它

@Target(ElementType. METHOD )// 声明了该内注只对方法有用

public@interfaceTest {

}

例子 5:

packagetest;

public@interfaceUncheckedExceptions {

Class<?extendsRuntimeException>[] value();

}

内注是个 Class 的数组类型。

3.2 内注的类型

关于内注的类型主义以下几点:

1. 普通annotation

有成员的annotation

2. marker annotation 类型

一个没有成员定义的annotation 类型被称为marker annotation 。这种annotation 类型仅使用自身的存在与否来为我们提供信息。如Override 。

3.meta-annotation :

meta -annotation 也称为元annotation ,它是被用来声明annotation 类型的annotation 。Java5.0 提供了一些标准的元-annotation 类型。如:

[target]

annotation 的target 是一个被标注的程序元素。target 说明了annotation 所修饰的对象范围:annotation 可被用于packages 、 types (类、接口、枚举、annotation 类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch 参数)。在annotation 类型的声明中使用了target 可更加明晰其修饰的目标。

[retention]

annotation 的retention 定义了该annotation 被保留的时间长短:某些annotation 仅出现在源代码中,而被编译器丢弃;而另一些却被编译在 class 文件中;编译在class 文件中的annotation 可能会被虚拟机忽略,而另一些在class 被装载时将被读取(请注意并不影响class 的执行,因为annotation 与class 在使用上是被分离的)。使用这个meta-annotation 可以对annotation 的“生命周期” 限制。

上面的例4 里声明的test 就是使用了@Retention (RetentionPolicy. RUNTIME ) 和

@Target (ElementType. METHOD ) 两个元内注进行声明的内注。前者是为了让内注能在运行时被处理,后者说明了该内注是用来修饰方法的。

3.3 内注的使用

标注的使用很简单,就是在要修饰的地方前面加上内注。

使用标准Annotation

@Override

public String toSting() {   // 注意方法名拼写错了

return "[" + super.toString() + "]";

}

本方法编译器会报错,因为使用了@Override标注之后编译器会检查父类是否有被重写的方法。显然上面的方法拼写错误,所以就会报错。

自定义内注使用

定义:

packageannotation;

importjava.lang.annotation.*;// import this to use @Documented

@Documented

public@interfaceClassPreamble {

String author();

String date();

intcurrentRevision()default1;

String lastModified()default"N/A";

String lastModifiedBy()default"N/A";

String[] reviewers();// Note use of array

}

使用:

@ClassPreamble(author ="John Doe", date ="3/17/2002", currentRevision =6, lastModified ="4/12/2004", lastModifiedBy ="Jane Doe", reviewers = {

"Alice","Bob","Cindy"}// Note array notation

)

publicclassTestAnno {

}

该内注提供了一个注释的模板。

3. 运行时处理内注

内注定义:

packagetest;

importjava.lang.annotation.*;

/**

* Indicates that the annotated method is a test method. This annotation should

* be used only on parameterless static methods.

*/

@Retention(RetentionPolicy. RUNTIME )

@Target(ElementType. METHOD )

public@interfaceTest {

}

使用 :

packagetest;

publicclassSample {

@Test

publicstaticvoidm1() {

}

publicstaticvoidm2() {

}

@Test

publicstaticvoidm3() {

thrownewRuntimeException("Boom");

}

publicstaticvoidm4() {

}

@Test

publicstaticvoidm5() {

}

publicstaticvoidm6() {

}

@Test

publicstaticvoidm7() {

thrownewRuntimeException("Crash");

}

publicstaticvoidm8() {

}

publicstaticvoidm9() {

}

}

测试:

packagetest;

importjava.lang.reflect.*;

publicclassRunTests {

publicstaticvoidmain(String[] args)throwsException {

intpassed =0, failed =0;

for(Method m : Class. forName (args[0]).getMethods()) {

if(m.isAnnotationPresent( Test .class)) {

try{

m.invoke(null);

passed++;

}catch(Throwable ex) {

System. out

.printf("Test %s failed: %s %n", m, ex.getCause());

failed++;

}

}

}

System. out .printf("Passed: %d, Failed %d%n", passed, failed);

}

}

运行 :java RunTests test.Sample 的结果如下:

Testpublicstaticvoidtest.Sample.m3() failed: java.lang.RuntimeException : Boom

Testpublicstaticvoidtest.Sample.m7() failed: java.lang.RuntimeException : Crash

Passed:2, Failed2

从代码和结果可以看到,通过 Java 反射可以访问声明为 RetentionPolicy.RUNTIME 类型的 java 内注 .

完!

本文部分内容参考了 :

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_28745821/article/details/114725742

java_ssm框架浅析_凨行的博客-爱代码爱编程

SSM框架介绍 SpringMVC springmvc是基于servlet的一种框架,也是spring框架的一部分,主要作用于接受请求和响应请求。 Spring spring是一个大容器是管理和控制对象的一种方式,主

java之注解(annotation)浅析_秃头哥编程的博客-爱代码爱编程

小弟还在新手阶段,所以只能起个“浅析”的名字,不求能带给大家多少进步,最大的作用就是自己总结一下,方便以后回顾,如果有人能从这篇文章中得到一点启示,那再好不过了。 先推荐一篇关于注解的文章,讲的很详细https://blo

java注解浅析_奔跑吧小蜗牛的博客-爱代码爱编程

注解(Annotation)是JDK1.5引入的机制,我们平时经常会遇到一些注解,比如@Override,@Test等,也知道这些注解是在哪些情况下使用的,但是却很少去关注注解这一机制本身,比如注解是如何定义的,注解的

java annotation实现原理浅析(上)_一个行走的民的博客-爱代码爱编程

0. 之前的一篇博客中写了写关于Annotation使用相关的,今天来分析下Annotation是实现原理 由于RetentionPolicy.SOURCE RetentionPolicy.CLASS的两种注解是JVM不

浅析annotation接口_jog熊吉的博客-爱代码爱编程

  这一次我们来看看注解的Annotation接口。 首先我们要知道什么是注解,注解这个特性是java5引入进来的,主要是在代码上附带上元数据或标记。这样的做法使代码与一些框架的配置项很好的结合起来,且增加了代码的可读性,Hibernate注解就是非常成功的使用。 Java本身为我们提供了三个注解,他们分别是 java,lang.Ov

java 注解浅析_奔跑的大白啊的博客-爱代码爱编程

前言     前段时间一直想了解下java的自定义注解,包括面试的时候也遇到过类似问题,今天总算有时间来学习下。 正文 注解(Annotation)概念     注解是Java SE 5.0版本开始引入的概念,

注解annotation实现原理与自定义注解浅析-爱代码爱编程

什么是注解? 对于很多初次接触的开发者来说应该都有这个疑问?Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、

浅析 Java 注解(Annotation)-爱代码爱编程

ava 5之后可以在源代码中嵌入一些补充信息,这种补充信息称为注解(Annotation),例如在方法覆盖中使用过的@Override注解,注解都是**@符号开头**的。 注解并不能改变程序运行的结果,不会影响程序运行的性能。有些注解可以在编译时给用户提示或警告,有的注解可以在运行时读写字节码文件信息。 五个基本注解 无论是哪一种注解,本质上都一