1. 简介
注解(也被称为元数据),为我们在代码中添加信息提供了一种形式化的方法。注解在一定程度上是把元数据与源代码文件结合在一起,而不是保存在外部文档中这一大趋势之下所催生的。
它可以提供用来完整的描述程序所需的信息,而这些信息是无法使用Java来表达的。因此,注解使得我们能够以将编译器来测试和验证的格式,存储有关程序的额外信息。注解可以用来生成描述符文件,甚至是新的类定义。通过使用注解,我们可以将这些元数据保存在Java源代码中,并利用Annotation
API为自己的注解构造处理工具。
注解可以生成更加干净易读的代码以及编译器类型检查等等。
注解(annotation)实在实际的源代码级别保存所有的信息,而不是某种注释性文字(comment),这使得代码更加简洁,便于维护。
2. 注解分类
按照运行机制分类 |
描述 |
源码注解 |
注解只在源码中存在,编译成.class文件就不存在了 |
编译时注解 |
注解只在源码和.class文件中都存在(例如:@override) |
运行时注解 |
在运行阶段还起作用,甚至影响运行逻辑的注解(例如:@Autowired) |
3. 内置注解:
(1)@override
表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法签名对不上被覆盖的方法,编译器就会发出错误提示。
(2)@Deprecated
如果程序员使用了注解为它的元素,那么编译器会发出警告信息。
(3)@SuppressWarnings
关闭不当的编译器警告信息(在java SE5 之前,也可以使用这个注解,不过被忽略不起作用)
4. 基本语法
4.1 定义注解
可以看到注解的定义很像接口的定义。事实上,与其他任何Java接口一样,注解也会被编译成class文件。
package com.qunar.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Annotation {
// 定义Description注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
// 使用@interface 关键字定义注解
public @interface Description{
// 成员以无参无异常方式声明
String desc();
String author();
// 可以使用default关键字为成员指定一个默认值
int age() default 18;
}
}
除了@符号以外,@Description的定义很像一个接口。定义注解的时候会需要一些元注解,如@Target和@Retention。@Target用来定义你的注解将用于什么地方(是一个方法上还是一个类上),@Retention用来定义该注解在哪一个级别上可用(在源代码上或者是类文件上或者是运行时),具体下面讲解。
4.2 注解元素
注解@Description中包含int元素age,以及String元素desc和author。注解元素可以使用的类型如下:
- 所有基本数据类型(int,float,boolean等)
- String
- Class
- enum
- Annotation
- 以上类型的数组
如果你使用了其他类型,那么编译器就会报错。注意,也不允许使用任何包装类型,不过由于自动打包的存在,这算不上什么限制。注解也可以作为元素的类型,也就是注解可以嵌套。
4.3 默认值限制
编译器对元素的默认值有些过分的挑剔。
首先,元素不能有不确定的值,也就是说元素必须要么有默认值,要么使用注解时提供元素的值。
其次,对于非基本类型的元素,无论是在源代码中声明时,或者是在注解接口中定义默认值时,都不能以null作为其值。为了这个约束,我们只能自己定义一些特殊的值,例如空字符串或者负数,来表示某个元素不存在。
4.4 元注解
元注解只负责注解其他的注解。
元注解 |
参数
|
描述 |
@Taget
|
CONSTRUCTOR |
构造器的声明 |
表示注解可以用于什么地方
|
FIELD |
域声明 |
METHOD |
方法声明 |
PACKAGE |
包声明 |
PARAMETER |
参数声明 |
TYPE |
类,接口或enum声明 |
LOCAL_VARIABLE |
局部变量声明 |
|
@Retention
|
SOURCE |
注解只在源码中存在,编译成.class文件就不存在了 |
表示需要在什么级别保存该注解信息
|
CLASS |
注解只会在.class文件存在,会被VM丢弃 |
RUNTIME |
VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息 |
@Document |
|
|
将此注解包含在Javadoc中 |
@Inherited |
|
|
允许子类继承父类中的注解 |
4.5 使用注解
语法:@<注解名称>(<成员名1> = <成员值1>,<成员名2> = <成员值2>,...)
package com.qunar.annotation;
import com.qunar.annotation.Annotation.Description;
public class Student {
private String name;
@Description(desc = "set name for student object" , author = "sjf0115")
public String getName() {
return name;
}
@Description(desc = "get name from student object" , author = "sjf0115", time = "2016-01-11")
public void setName(String name) {
this.name = name;
}
}
5. 解析注解
通过反射机制获取类,函数或者成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。
package com.qunar.annotation;
import java.lang.reflect.Method;
import com.qunar.annotation.Annotation.Description;
public class ParseAnnotation {
public static void main(String[] args){
Class<?> class1 = null;
try {
// 使用类加载器加载类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 判断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的所有方法
Method[] methods = class1.getMethods();
// 遍历所有方法
for (Method method : methods) {
// 判断方法上是否有Description注解
isExits = method.isAnnotationPresent(Description.class);
if(isExits){
Description description = method.getAnnotation(Description.class);
System.out.println("方法注解:" + description.toString());
}//if
}//for
}
}
运行结果:
方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-12,desc=setnameforstudentobject,author=sjf0115)
方法注解:@com.qunar.annotation.Annotation$Description(time=2016-01-11,desc=getnamefromstudentobject,author=sjf0115)
|
package com.qunar.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import com.qunar.annotation.Annotation.Description;
public class ParseAnnotation {
public static void main(String[] args){
Class<?> class1 = null;
try {
// 使用类加载器加载类
class1 = Class.forName("com.qunar.annotation.Student");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 判断Student类上是否有Description注解
boolean isExits = class1.isAnnotationPresent(Description.class);
if(isExits){
// 注解实例
Description desc = class1.getAnnotation(Description.class);
System.out.println("注解:" + desc.toString());
}//if
// 获取Student类上的所有方法
Method[] methods = class1.getMethods();
// 遍历所有方法
for (Method method : methods) {
// 方法上获取所有的注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof Description){
System.out.println("Description注解:" + annotation.toString());
}//if
}//for
}//for
}
}
这两个程序都用到了反射的方法:getMethods()和getAnnotation(),它们都属于AnnotatedElement接口(Class,Method与Field等类都实现了该接口)。getAnnotation()方法返回指定类型的注解对象,在这里就是Description。如果被注解的方法上没有该类型的注解,则返回null值。
分享到:
相关推荐
自JDK1.5之后引入注解之后,各个框架中都提供了支持注解的方式。在日常开发中慢慢的将XML许多的配置转换成注解, 此demo分别对 类注解,方法注解,属性注解进行了说明.
关于SSH2基础的Java全注解式的开发框架的基本搭建,可供参考。
本注解,通过代码对java,struts,spring,hibernate内的各种情况进行解释,是不可多得的资料
1.JAVA开发的电子地图 2.Java地图编辑器 3.MapXtreme+for+Java例子集+from+MapInfo+KnowledgeBase 4.mapxtreme+for+java+的开发实例 5.有注解.入门用
本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...
Java开发自定义注解详解.doc
java spring 框架及注解 总结,本人在项目开发中总结的,希望对大家有所帮助
基于java的开发源码-UIMA注解类 uimaFIT.zip
【奔跑吧,小恐龙!】Java开发的小游戏,多线程开发,可以播放背景音乐,具有动画效果,完整源码带注解,可以直接编译。
Java注解Annotation用起来很方便,也越来越流行,由于其简单、简练且易于使用等特点,很多开发工具都提供了注解功能,不好的地方就是代码入侵比较严重,所以使用的时候要有一定的选择性。 这篇文章将利用注解,来做...
mapxtreme for java 的开发实例,有注解.入门用,希望对大家有所帮助,代码只是初级应用,大家可以从本基础进行改造。
利用annotation(注解)开放简化java开放步骤
不论是开发框架、库,还是进行特定行为的配置和处理,都可以从使用注解中获益。 使用场景: 以下是一些适合使用Java注解的常见场景: 在源代码中标记和解析特定元素,如类、方法、字段等。 通过注解来配置和参数化...
基于Java注解的Drools业务规则开发框架设计实现.pdf
里边主要是 junit-4.12.jar hamcrest-core-1.3.jar l两个jar包,是使用junit4,单元测试需要导入的包
在开发的过程中,用到的可以看下,建议大家可以下载来看下
利用JAVA注解实现SQL语句自动生成 编写对应Entity添加相关注解,并通过SqlUtil工具,传入相关参数生成SQL语句 例如:要生成对应数据库Person的SQL增删改查 SqlUtil.create(Person.class) SqlUtil.insert(Person....
java注解详解[文].pdf
自定义java注解开发,javabean中某方法添加该自定义注解,配置该方法相关信息指标,通过全局扫描该注解获取全部方法及相关指标,自动执行方法(本demo用于系统监控开发)
同时,在3.x版本之后,它开始之初Rest风格的请求URL,为开发者提供了开发基于Restful访问规则的项目提供了帮助。 SpringData是一组技术合集。里面包含了JDBC,Data JPA,Data Redis,Data Mongodb,Data Rabbit,...