以Java EE中典型的SSH架构来说,Spring、Struts和Hibernate这三个框架都有自己的XML格式的配置文件。这些配置文件需要与Java源代码保存同步,否则的话就可能出现错误。而且这些错误有可能到了运行时刻才被发现。JDK 5中引入了源代码中的注解(annotation)这一机制。注解使得Java源代码中不但可以包含功能性的实现代码,还可以添加元数据。注解的功能类似于代码中的注释,所不同的是注解不是提供代码功能的说明,而是实现程序功能的重要组成部分。Java注解已经在很多框架中得到了广泛的使用,用来简化程序中的配置。
一,使用注解
@Override:有两个功能。
1,这是你的IDE编辑器为你自动加上的一个标志,告诉你下面这个方法是从父类/接口继承过来的,其中的方法需要你重写。
2,编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。
@SuppressWarnings:该批注的作用是给编译器一条指令,告诉它对被批注的代码元素内部的某些警告保持静默。
在程序中该批注可以携带参数,如:@SuppressWarnings("unchecked")。如下所示,该标注可以携带的参数和对应功能
关键字(参数) | 功能 |
deprecation | 使用了不建议使用的类或方法的警告 |
unchecked | 执行了未检查的转换是的警告 |
fallthrough | 当Switch块直接通往下一种情况,而没有Break时的警告 |
path | 在类路径、源文件路径不存在时的警告 |
serial | 当在可序列化的类上缺少serialVersionUID时的警告 |
finally | 任何finally子句不能正常运行时的警告 |
all | 关于以上情况的所有警告 |
二,元注解
@Target 说明了注解对象所修饰的范围。该注解可被用于packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。
该注解所带参数的取值有7种。如:@Target(ElementType.TYPE)
(ElementType)的参数 | 功能 |
CONSTRUCTOR | 表示该注解适用于整个构造器 |
FIELD | 表示该注解适用于整个域(表示{}之间的代码块) |
LOCAL_VARIABLE | 表示该注解适用于局部变量 |
METHOD | 表示该注解适用于类中对应的方法 |
PACKAGE | 表示该注解适用于程序中的包 |
PARAMETER | 表示该注解适用于方法中的参数 |
TYPE | 表示该注解适用于描述类、接口或者ENUM声明 |
该注解所带参数有3种取值。如:@Retention(RetentionPoicy.RUNTIME)
(RetentionPoicy)的参数 | 功能 |
SOURCE | 仅在编写的源代码中保留 |
CLASS | 在编译到class文件中,在运行时会被丢弃 |
RUNTIME | 在虚拟机中执行时会被运行 |
@Documented 描述其他类型的注解应该被作为被标注程序的公共API,可以被javadoc此类的工具文档化。
@Inherited 是一个标记注解,阐述了某个被标注的类是继承的。并被标注过的类的子类所接受,该类并不从他所继承的接口继承,或者方法并不从他所重载的方法继承。
三,自定义注解
public @interface 注解名{定义体}
在定义注解时,不能继承其他注解或接口。@interface声明的注解的每一个方法实际上是声明了一个配置参数,方法的名称就是参数名称,返回值类型就是参数的类型(返回值类型只能是基本的类型、Class、String、enum)
如果只有一个参数成员,最好把参数名称设为"value",后加小括号。
注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,非基本类型的注解元素的值不可为null。因此, 使用空字符串或0作为默认值是一种常用的做法。这个约束使得处理器很难表现一个元素的存在或缺失的状态,因为每个注解的声明中,所有元素都存在,并且都具有相应的值,为了绕开这个约束,我们只能定义一些特殊的值,例如空字符串或者负数,一次表示某个元素不存在。
package annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 水果名称注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
String value() default "";
}
/**
* 水果颜色注解
* @author peida
*
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
/**
* 颜色枚举
* @author peida
*
*/
public enum Color{ BULE,RED,GREEN};
/**
* 颜色属性
* @return
*/
Color fruitColor() default Color.GREEN;
}
package annotation;
import annotation.FruitColor.Color;
public class Apple {
@FruitName("Apple")
private String appleName;
@FruitColor(fruitColor=Color.RED)
private String appleColor;
public void setAppleColor(String appleColor) {
this.appleColor = appleColor;
}
public String getAppleColor() {
return appleColor;
}
public void setAppleName(String appleName) {
this.appleName = appleName;
}
public String getAppleName() {
return appleName;
}
public void displayName(){
System.out.println("水果的名字是:苹果");
}
}