怎样优雅地使用javajava自定义注解的使用

java中的内置注解Annotation
背景知识:
&&&&&& 从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范。注释是以&@注释名&在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value=&unchecked&)。注释可以附加在package, class, method, field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制实现对这些元数据的访问。如果没有外部解析工具等对其加以解析和处理的情况,本身不会对的源代码或class文件等产生任何影响,也不会对它们的执行产生任何影响。
&&&& 元数据的作用,大致可分为三种:编写文档,通过代码里标识的元数据生成文档;代码分析,通过代码里标识的元数据对代码进行分析;编译检查,通过代码里标识的元数据让编译器能实现基本的编译检查。
JDK5内置的基本注释
&&& JDK5内置了一些常用的注释,可以在编译时帮我们捕获部分编译错误,及提示信息,下面介绍下这些注释的用法:
1、@Override定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;代码如下:
public class OverrideDemo {
&&& @Override
&&& public String tostring() {
&&&&&&& return super.toString();
在编译时,会提示以下错误信息:
OverrideTest.java:4: 方法未覆盖其父类的方法
&&&&&&&&& @Override
&&&&&&&& ^1 错误
2、@Deprecated定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。使用@Deprecated的示例代码如下:
public class DeprecatedDemo {
&&& public static void main(String[] args) {
&&&&&&&& DeprecatedClass.DeprecatedMethod();
class DeprecatedClass {
&&& @Deprecated
&&& public static void DeprecatedMethod() {
在编译时,会得到以下提示信息:
注意:DeprecatedDemo.java 使用或覆盖了已过时的 API。
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
要注意@Deprecated与@deprecated的区别,@deprecated是为了生成文档的需要,例如:
class DeprecatedClass {
@Deprecated
&&& public static void DeprecatedMethod() {
3、@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下:
通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数unchecked为例,为你展示如何使用@SuppressWarnings注释,示例代码如下:
import java.util.L
import java.util.ArrayL
public class SuppressWarningsDemo {
&&&&&&& public static List cache = new ArrayList();
&&&&&&& //@SuppressWarnings(value = &unchecked&)
&&&&&&& public void add(String data) {
&&&&&&&&&&& cache.add(data);
当我们不使用@SuppressWarnings注释时,编译器就会有如下提示:
注意:SuppressWarningsDemo.java 使用了未经检查或不安全的操作。
注意:要了解详细信息,请使用 -Xlint:unchecked 重新编译。
另外,由于@SuppressWarnings注释只有一个参数,并且参数名为value,所以我们可以将上面一句注释简写为
@SuppressWarnings(&unchecked&)。
同时参数value可以取多个值如:
@SuppressWarnings(value={&unchecked&, &deprecation&})
或@SuppressWarnings({&unchecked&, &deprecation&})。
摘自& IT胖子的专栏一、注解的基本概念
注解是JDK1.5及以后版本引入的,它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的,它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。(摘自)
按照运行机制,注解可以分为三类:1、源码注解:即注解只在源代码中存在,在编译成.class文件后就不存在了;2、编译时注解:即在源码和编译的.class文件中都存在,例如常见的JDK 注解@Override、@Deprecated、@SuppressWarings;3、运行时注解:即注解在运行时仍然存在,甚至可能会影响程序的运行逻辑,例如Spring框架中用到的@Autowired注解。
我们也可以按照来源来将注解划分为三类:1、来自JDK的注解,就比如前面提到的@Override、@Deprecated、@SuppressWarings;2、来自第三方框架的注解,例如Spring的@Autowired;3、当然还有我们自己定义的注解。
还有一种特殊的注解,元注解,就是指注解的注解,这在自定义注解时经常使用。
二、自定义注解
我们可以通过自定义注解来实现我们自己想要的功能,下面通过一个简单的例子来讲解一下自定义注解的一些知识,下面的代码是一个简单的自定义注解。
package com.imooc.
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.I
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
String name();
int age() default 18;
首先我们可以看到,我们是使用@interface关键字定义注解的,其中注解里定义的类似于一个方法的例如String name();其实是注解的成员,注解的成员通常以无参无异常的方式声明的,我们也可以用default关键字为成员指定一个默认值。这里需要注意的是注解的成员的类型是受限的,只能是基本数据类型或者String,Class,Annotation,Enumeration这几种类型,如果一个注解只有一个成员,那么这个成员就必须取名为value(),在使用注解时可以不显式声明成员名称和等于号(=)。注解也可以没有成员,没有成员的注解称为标识注解。
除了注解定义的成员,我们发现在注解定义上面还有几个注解,这些注解就是元注解,下面来简单分析以下这几个元注解:@Target表示定义的注解的作用域,通常作用域有constructor(构造方法声明),field(字段声明),local_variable(局部变量声明),method(方法声明),package(包声明),parameter(参数声明),type(类,接口声明);@Retention表示定义的注解的运行周期,主要包括source:只在源码显示,编译时会丢弃,class:编译时会记录到class中,运行时忽略,runtime:运行时存在,可以通过反射读取;@Inherited表示被注解可以被子类继承;@Documented表示生成JavaDoc文档时会将注解写入文档。
当我们自定义了一个注解后就可以使用这个注解了,使用注解的语法是:@注解名(成员名=成员值,成员名=成员值……)
三、解析注解
在我们自定义了注解之后,可以通过反射获取类、方法或成员上运行时的注解信息,从而实现动态控制程序运行时逻辑的目的。下面通过一个实例来解析上面的例子中定义的注解。我们先定义一个类,类名为Boy,在这个类上和类的方法上使用注解,代码如下。
package com.imooc.
@Description(name=&A Class boy&, age=20)
public class Boy {
@Description(name=&A Method boy&, age=20)
public String name() {
public int age() {
}然后我们再写一个解析注解的类TestAnnotation,通过反射来获取注解的信息。
package com.imooc.
import java.lang.annotation.A
import java.lang.reflect.M
public class TestAnnotation {
public static void main(String[] args) {
//1、获取Class信息
Class clazz = Boy.
//2、通过反射判断类上是否存在注解
if(clazz.isAnnotationPresent(Description.class)) {
//3、获取到类上的注解
Description desc
= (Description) clazz.getAnnotation(Description.class);
//4、获取类上注解的信息
System.out.println(&name=& + desc.name() + &,age=& + desc.age());
//5、通过反射获取类的方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
//6、判断方法上是否有注解
if(method.isAnnotationPresent(Description.class)) {
//7、获取方法上的注解
Description methodDesc = method.getAnnotation(Description.class);
//8、获取方法上注解的信息
System.out.println(&第一种方式获得注解:name=& + methodDesc.name() + &,age=& + methodDesc.age());
//9、获取方法上所有的注解信息
Annotation[] anns = method.getAnnotations();
for (Annotation annotation : anns) {
//10、遍历注解获取对应的注解信息
if(annotation instanceof Description) {
Description methodDesc = (Description)
System.out.println(&第二种方式获得注解:name=& + methodDesc.name() + &,age=& + methodDesc.age());
运行程序,程序执行如下结果,说明我们自定义的注解解析成功了。
name=A Class boy,age=20
第一种方式获得注解:name=A Method boy,age=20
第二种方式获得注解:name=A Method boy,age=20接下来我们思考一下,定义一个接口Person,然后让Boy实现这个接口,然后在Person上使用注解,代码如下:
package com.imooc.
@Description(name=&A Class boy&, age=20)
public interface Person {
@Description(name=&A Method boy&, age=20)
public String name();
public int age();
}package com.imooc.
public class Boy implements Person {
public String name() {
public int age() {
这时再运行TestAnnotation,我们发现控制台并没有打印任何输出,这说明@Inherited这个元注解对与接口的implements是不起作用的,那如果我们将接口Person改成抽象类,让Boy继承这个抽象类结果会是怎样呢?
package com.imooc.
@Description(name=&A Class boy&, age=20)
public abstract class Person {
@Description(name=&A Method boy&, age=20)
public String name(){
public int age(){
package com.imooc.
public class Boy extends Person {
public String name() {
public int age() {
运行程序,控制台打印如下输出。
name=A Class boy,age=20这说明@Inherited这个元注解对继承extends是起作用的,但是只会继承类上的注解,并不会继承该类方法上的注解。
四、一个简单实例的记录
这里简单记录一个注解实现的实例,主要用于根据数据库表和表中的字段进行组合,自动生成相应的SQL,下面是代码。
package com.imooc.annotation.
@Table(&user&)
public class UserBean {
@Column(&id&)
@Column(&user_name&)
private String userN
@Column(&nick_name&)
private String nickN
@Column(&age&)
@Column(&sex&)
@Column(&city&)
@Column(&email&)
@Column(&phone&)
public int getId() {
public void setId(int id) {
public String getUserName() {
return userN
public void setUserName(String userName) {
this.userName = userN
public String getNickName() {
return nickN
public void setNickName(String nickName) {
this.nickName = nickN
public int getAge() {
public void setAge(int age) {
this.age =
public String getSex() {
public void setSex(String sex) {
this.sex =
public String getCity() {
public void setCity(String city) {
this.city =
public String getEmail() {
public void setEmail(String email) {
this.email =
public String getPhone() {
public void setPhone(String phone) {
this.phone =
package com.imooc.annotation.
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.I
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {
String value();
package com.imooc.annotation.
import java.lang.annotation.D
import java.lang.annotation.ElementT
import java.lang.annotation.I
import java.lang.annotation.R
import java.lang.annotation.RetentionP
import java.lang.annotation.T
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Column {
String value();
package com.imooc.annotation.
import java.lang.reflect.F
import java.lang.reflect.M
public class SQLUtil {
public static void main(String[] args) throws Exception {
UserBean user = new UserBean();
user.setId(1);
user.setUserName(&Jack&);
user.setEmail(&,,&);
System.out.println(generateSQL(user));
public static String generateSQL(Object obj) throws Exception {
StringBuffer sb = new StringBuffer();
Class clazz = obj.getClass();
if(clazz.isAnnotationPresent(Table.class)) {
Table table = (Table) clazz.getAnnotation(Table.class);
sb.append(&select * form &).append(table.value()).append(& where 1=1 &);
Field[] fields = clazz.getDeclaredFields();
for(Field field : fields) {
if(field.isAnnotationPresent(Column.class)) {
Column column = field.getAnnotation(Column.class);
String columnName = column.value();
String getMethodName = &get& + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
Method getMethod = clazz.getMethod(getMethodName);
Object returnValue = getMethod.invoke(obj);
if(returnValue instanceof String) {
if(returnValue != null) {
if(((String) returnValue).contains(&,&)) {
String[] spiltStrs = ((String) returnValue).split(&,&);
sb.append(& and & + columnName + & in(&);
for (String spiltStr : spiltStrs) {
sb.append(& '& + spiltStr + &', &);
sb.append(&) &);
sb.append(& and & + columnName + &='& + returnValue + &' &);
if(returnValue instanceof Integer) {
if((int)returnValue != 0) {
sb.append(& and & + columnName + &=& + returnValue + & &);
return sb.toString();
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:35510次
排名:千里之外
原创:42篇
(1)(3)(5)(3)(7)(11)(13)
(window.slotbydup = window.slotbydup || []).push({
id: '4740887',
container: s,
size: '250,250',
display: 'inlay-fix'Java注解一 注解的含义
在学习Spring框架的时候就觉得注解很神奇,为什么简单的注解有这么神奇的功能,一直想去了解其中的奥秘,可惜的是到今天才实践。在Spring框架中一个@Controller 就可以把一个简单的类变得神奇,我一直以为这个注解干了所有的事。然而并非我想的那样。
找了不少资料,感觉讲的都不是很好,终于看到了《java核心技术2》这本书才了解了一些。 在本书中提及:
注解是插入到源代码中使用其他工具可以对其进行处理的标签。 注解并不会改变代码,而是这些工具产生了这些所用,所以没有工具处理的注解也不会发挥效用。这些工具可以在源代码的层次上进行操作,或者是可以处理在其中放置了注解的类文件。
注解可以使用在
附属文件的自动生成。例如部署描述符或者bean信息类。
测试、日志、事务语义等代码的自动生成。
在Java中自带了几个注解,这些注解是为了注解别的注解,所以称为meta注解。
其中包括了
@Retention:这个注解注在其他注解上,并用来说明如何存储已被标记的注解。可能的值是:
SOURCE:表明这个注解会被编译器忽略,并只会保留在源代码中。
CLASS:表明这个注解会通过编译驻留在CLASS文件,但会被JVM在运行时忽略,正因为如此,其在运行时不可见。
RUNTIME:表示这个注解会被JVM获取,并在运行时通过反射获取
@Target:这个注解用于限制某个元素可以被注解的类型。例如:
ANNOTATION_TYPE 表示该注解可以应用到其他注解上
CONSTRUCTOR 表示可以使用到构造器上
FIELD 表示可以使用到域或属性上
LOCAL_VARIABLE表示可以使用到局部变量上。
METHOD可以使用到方法级别的注解上。
PACKAGE可以使用到包声明上。
PARAMETER可以使用到方法的参数上
TYPE可以使用到一个类的任何元素上。
@Documented:被注解的元素将会作为Javadoc产生的文档中的内容。注解都默认不会成为成为文档中的内容。这个注解可以对其它注解使用。
@Inherited:在默认情况下,注解不会被子类继承。被此注解标记的注解会被所有子类继承。这个注解可以对类使用。
@Deprecated:说明被标记的元素不应该再度使用。这个注解会让编译器产生警告消息。可以使用到方法,类和域上。相应的解释和原因,包括另一个可取代的方法应该同时和这个注解使用。
@SuppressWarnings:说明编译器不会针对指定的一个或多个原因产生警告。
@Override:向编译器说明被注解元素是重写的父类的一个元素。在重写父类元素的时候此注解并非强制性的,不过可以在重写错误时帮助编译器产生错误以提醒我们。比如子类方法的参数和父类不匹配,或返回值类型不同。
@SafeVarargs:断言方法或者构造器的代码不会对参数进行不安全的操作。在Java的后续版本中,使用这个注解时将会令编译器产生一个错误在编译期间防止潜在的不安全操作。
本次只是简单的介绍了注解,后续会讲解怎么自定义注解和一些例子。
由于jekyll的环境非常难维护,所以转转阵营了,blog换为Hexo的了,而且换了主题。博客的地址是
,我的博客中的排版更为美观,欢迎大家去看我的博客,也可以用邮箱订阅。
本文已收录于以下专栏:
相关文章推荐
本文引用与张孝祥老师的视频总结       1.注解相当于一种标记加了注解就等于打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具包和其他程序可以用反射来了解你的类以及各种元素...
xxx cannot be resolved to a type引言:     eclipse新导入的项目经常可以看到“XX cannot be resolved to a type”的报错信息。本文...
做为一个程序员可能在学习技术,了解行业新动态,解决问题时经常需要阅读英文的内容;而像我这样的英文小白就只能借助翻译工具才能理解个大概;不禁经常感慨,英文对学习计算机相关知识太重要了!最近发现IBM的云...
  元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解...
本篇文章基于retrofit-2.1进行分析.
1. 各个注解的含义及使用
1.1 Body注解:
作用于方法的参数使用该注解定义的参数不可为null当你发送一个post或put...
Web Service 元数据注释(JSR 181)
@WebService
   1、serviceName: 对外发布的服务名,指定 Web Service 的服务名称:ws...
@Controller
o @Service
o @Autowired
o @RequestMapping
在函数内部,有两个特殊的对象:arguments和this。arguments是一个类似数组的对象,包含着传入函数中的所有参数。该对象有一个callee属相,该属性是一个指针,指向拥有这个argume...
写在前面本篇文章基于retrofit-2.1进行分析.1. 各个注解的含义及使用1.1 Body注解:
作用于方法的参数
使用该注解定义的参数不可为null
当你发送一个post或put请求,但是又不...
声明Bean的注解:
@Component : 组件,没有明确的角色@Service : 在业务逻辑层(service层)使用@Repository : 在数据访问层(dao层)使用.@Cont...
他的最新文章
讲师:王哲涵
讲师:王渊命
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)Java中的注解是如何工作的
中的注解是如何工作的:自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分。开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解。
这篇文章中,我将向大家讲述到底什么是注解,为什么要引入注解,注解是如何工作的,如何编写自定义的注解(通过例子),什么情况下可以使用注解以及最新注解和ADF(应用开发框架)。这会花点儿时间,所以为自己准备一杯咖啡,让我们来进入注解的世界吧。
注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。比如,下面这段代码:
public String toString() {
return &This is String Representation of current object.&;
`上面的代码中,我重写了toString()方法并使用了@Override注解。但是,即使我不使用@Override注解标记代码,程序也能够正常执行。那么,该注解表示什么?这么写有什么好处吗?事实上,@Override告诉编译器这个方法是一个重写方法(描述方法的元数据),如果父类中不存在该方法,编译器便会报错,提示该方法没有重写父类中的方法。如果我不小心拼写错误,例如将toString()写成了toStrring(){double r},而且我也没有使用@Override注解,那程序依然能编译运行。但运行结果会和我期望的大不相同。现在我们了解了什么是注解,并且使用注解有助于程序。
Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符。它是一种由JSR-175标准选择用来描述元数据的一种工具。
**为什么要引入注解?**
使用Annotation之前(甚至在使用之后),XML被广泛的应用于描述元数据。不知何时开始一些应用开发人员和架构师发现XML的维护越来越糟糕了。他们希望使用一些和代码紧耦合的东西,而不是像XML那样和代码是松耦合的(在某些情况下甚至是完全分离的)代码描述。如果你在Google中搜索&XML vs. annotations&,会看到许多关于这个问题的辩论。最有趣的是XML配置其实就是为了分离代码和配置而引入的。上述两种观点可能会让你很疑惑,两者观点似乎构成了一种循环,但各有利弊。下面我们通过一个例子来理解这两者的区别。
假如你想为应用设置很多的常量或参数,这种情况下,XML是一个很好的选择,因为它不会同特定的代码相连。如果你想把某个方法声明为服务,那么使用Annotation会更好一些,因为这种情况下需要注解和方法紧密耦合起来,开发人员也必须认识到这点。
另一个很重要的因素是Annotation定义了一种标准的描述元数据的方式。在这之前,开发人员通常使用他们自己的方式定义元数据。例如,使用标记interfaces,注释,transient关键字等等。每个程序员按照自己的方式定义元数据,而不像Annotation这种标准的方式。
目前,许多框架将XML和Annotation两种方式结合使用,平衡两者之间的利弊。
**Annotation是如何工作的?怎么编写自定义的Annotation?**
在讲述这部分之前,建议你首先下载Annotation的示例代码AnnotationsSample.zip 。下载之后放在你习惯使用的IDE中,这些代码会帮助你更好的理解Annotation机制。
编写Annotation非常简单,可以将Annotation的定义同接口的定义进行比较。我们来看两个例子:一个是标准的注解@Override,另一个是用户自定义注解@Todo。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
对于@Override注释你可能有些疑问,它什么都没做,那它是如何检查在父类中有一个同名的函数呢。当然,不要惊讶,我是逗你玩的。@Override注解的定义不仅仅只有这么一点代码。这部分内容很重要,我不得不再次重复:Annotations仅仅是元数据,和业务逻辑无关。理解起来有点困难,但就是这样。如果Annotations不包含业务逻辑,那么必须有人来实现这些逻辑。元数据的用户来做这个事情。Annotations仅仅提供它定义的属性(类/方法/包/域)的信息。Annotations的用户(同样是一些代码)来读取这些信息并实现必要的逻辑。
当我们使用Java的标注Annotations(例如@Override)时,JVM就是一个用户,它在字节码层面工作。到这里,应用开发人员还不能控制也不能使用自定义的注解。因此,我们讲解一下如何编写自定义的Annotations。
我们来逐个讲述编写自定义Annotations的要点。上面的例子中,你看到一些注解应用在注解上。
J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:
@Documented &注解是否将包含在JavaDoc中
@Retention &什么时候使用该注解
@Target? &注解用于什么地方
@Inherited & 是否允许子类继承该注解
@Documented&一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
@Retention& 定义该注解的生命周期。
RetentionPolicy.SOURCE & 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS & 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME& 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target & 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。
ElementType.TYPE:用于描述类、接口或enum声明
ElementType.FIELD:用于描述实例变量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一个注释
ElementType.PACKAGE 用于记录java文件的package信息
@Inherited & 定义该注释和子类的关系
那么,注解的内部到底是如何定义的呢?Annotations只支持基本类型、String及枚举类型。注释中所有的属性被定义成方法,并允许提供默认值。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default &Yash&;
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
下面的例子演示了如何使用上面的注解。
@Todo(priority = Todo.Priority.MEDIUM, author = &Yashwant&, status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But it&s not complete yet
如果注解中只有一个属性,可以直接命名为&value&,使用时无需再标明属性名。
@interface Author{
String value();
@Author(&Yashwant&)
public void someMethod() {
但目前为止一切看起来都还不错。我们定义了自己的注解并将其应用在业务逻辑的方法上。现在我们需要写一个用户程序调用我们的注解。这里我们需要使用反射机制。如果你熟悉反射代码,就会知道反射可以提供类名、方法和实例变量对象。所有这些对象都有getAnnotation()这个方法用来返回注解信息。我们需要把这个对象转换为我们自定义的注释(使用 instanceOf()检查之后),同时也可以调用自定义注释里面的方法。看看以下的实例代码,使用了上面的注解:
Class businessLogicClass = BusinessLogic.
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(& Method Name : & + method.getName());
System.out.println(& Author : & + todoAnnotation.author());
System.out.println(& Priority : & + todoAnnotation.priority());
System.out.println(& Status : & + todoAnnotation.status());
注解的功能很强大,Spring和Hebernate这些框架在日志和有效性中大量使用了注解功能。注解可以应用在使用标记接口的地方。不同的是标记接口用来定义完整的类,但你可以为单个的方法定义注释,例如是否将一个方法暴露为服务。
在最新的servlet3.0中引入了很多新的注解,尤其是和servlet安全相关的注解。
HandlesTypes &该注解用来表示一组传递给ServletContainerInitializer的应用类。
HttpConstraint & 该注解代表所有HTTP方法的应用请求的安全约束,和ServletSecurity注释中定义的HttpMethodConstraint安全约束不同。
HttpMethodConstraint & 指明不同类型请求的安全约束,和ServletSecurity 注解中描述HTTP协议方法类型的注释不同。
MultipartConfig &该注解标注在Servlet上面,表示该Servlet希望处理的请求的 MIME 类型是 multipart/form-data。
ServletSecurity该注解标注在Servlet继承类上面,强制该HTTP协议请求遵循安全约束。
WebFilter & 该注解用来声明一个Server过滤器;
WebInitParam & 该注解用来声明Servlet或是过滤器的中的初始化参数,通常配合 @WebServlet 或者 @WebFilter 使用。
WebListener &该注解为Web应用程序上下文中不同类型的事件声明监听器。
WebServlet &该注解用来声明一个Servlet的配置。
ADF (应用程序框架)和注解
现在我们开始讨论文章的最后一部分了。应用程序框架,被称为ADF,由开发用来创建Oracle融合应用。我们已经了解了注解的优缺点,也知道如何编写自定义的注解,但我们应该将注解应用在ADF的哪部分呢?ADF是否提供了一些朴素的注解?很好的问题,确实在ADF中大量使用注解有一些限制。
之前提到的应用框架如Spring和Hibernate使用AOP(面向侧面的程序设计)。在AOP中,框架提供了一种机制,在事件的预处理和后续处理中注入代码。例如:你有一个钩子用来在方法执行之前和之后添加代码,所以你可以在这些地方编写你的用户代码。ADF不使用AOP。如果我们有任何注解的用例可用,我们可能需要通过继承的方式实现。

我要回帖

更多关于 java 不建议使用注解 的文章

 

随机推荐