Java 注解

1 什么是注解
Java注解是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符,注解相当于源代码的元数据。注解推出的目的是为了减少配置,让注解代替配置。

2 注解的应用场景
1)框架。注解广泛用于各个框架中,用于节省配置文件工作,例如Struts,Spring,Hibernate,JUnit等框架。

3 内置注解
Java提供了3个内置注解。
1)@Override,表示当前的方法定义将覆盖超类中的方法,仅能描述方法。
2)@Deprecated,使用了注解为它的元素编译器将发出警告,因为注解@Deprecated是声明被弃用的代码。可以描述类、方法和属性。
3)@SuppressWarnings,关闭不当编译器警告信息。可以描述@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}),@Target属于元注解,下面解释@Target的含义。
4 元注解
元注解是描述注解的注解,有如下几个元注解。
1)@Retention
表示需要在什么级别保存该注解信息。可选的参数包括:
SOURCE:注解将被编译器丢弃,例如@Override注解就没有必要留到运行期。
CLASS:注解在class文件中可用,但会被VM丢弃
RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息。
2)@Target
表示该注解可以用于什么地方,可能的ElementType参数有:
CONSTRUCTOR:构造器的声明
FIELD:域声明(包括enum实例)
LOCAL_VARIABLE:局部变量声明
METHOD:方法声明
PACKAGE:包声明
PARAMETER:参数声明
TYPE:类、接口(包括注解类型)或enum声明

如果要用在多个地方,可以用逗号隔开,例如@SuppressWarnings的元注解。
如果不定义@Target则表示可以用在以上所有地方。

3)@Document
将注解包含在Javadoc中
4)@Inherited
允许子类继承父类中的注解
5 自定义注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();
public String value() default "hello";
}


用@interface定义注解,注意同接口定义相比有个@,方法名就是要描述注解的属性,可以通过default设定默认值。
6 代码示例
//自定义注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
public String name();
public String value() default "hello";
}

//使用自定义注解描述类
@MyAnnotation(name="frank1234")
public class AnnnotationClass {
@MyAnnotation(name="frank1234",value="helloworld annotation fieldtype")
private String field1;
@MyAnnotation(name="frank1234", value="helloworld annotation methodtype")
public void test() {
}
public void test(@MyAnnotation(name="frank1234",value="helloworld annotaion parametertype")String str){

}
}
//测试类
public class AnnotationMain {
public static void main(String[] args) throws Exception{
classAnnotation();
methodAnnotation();
fieldAnnotation();
}
private static void classAnnotation() throws Exception{
Class clazz = AnnnotationClass.class;
boolean isAnnotation = clazz.isAnnotationPresent(MyAnnotation.class);
Annotation[] annotations = clazz.getDeclaredAnnotations();

for(Annotation annotation:annotations){
MyAnnotation myAnnotation = (MyAnnotation)annotation;
System.out.println("class annotation:" + myAnnotation.name() + "," + myAnnotation.value());
}
}
private static void methodAnnotation() throws Exception{
Class clazz = AnnnotationClass.class;
Method[] methods = clazz.getDeclaredMethods();
for(int i=0;i<methods.length;i++){
Method method = methods[i];
if(method.getName().equals("test")){
Annotation[] annotations = method.getAnnotations();
for(Annotation annotation:annotations){
MyAnnotation myAnnotation = (MyAnnotation)annotation;
System.out.println("method annotation:"+myAnnotation.name()+","+myAnnotation.value());
}
}
}
Method parameterMethod = clazz.getDeclaredMethod("test",String.class);
Annotation[][] parameterAnnotations = parameterMethod.getParameterAnnotations();
for(int i=0;i<parameterAnnotations.length;i++){
for(int j=0;j<parameterAnnotations[i].length;j++){
MyAnnotation parameterAnnotation = (MyAnnotation)parameterAnnotations[i][j];
System.out.println("method annotation parametertype:"+parameterAnnotation.name()+","+parameterAnnotation.value());
}
}

}
private static void fieldAnnotation() throws Exception{
Class aClass = AnnnotationClass.class;
Field[] fields = aClass.getDeclaredFields();
for(int i=0;i<fields.length;i++){
Field field = fields[i];
if(field.getName().equals("field1")){
Annotation[] annotations = field.getAnnotations();
for(Annotation annotation:annotations){
MyAnnotation myAnnotation = (MyAnnotation)annotation;
System.out.println("field annotation:"+myAnnotation.name()+","+myAnnotation.value());
}
}
}
}
}
输出结果:
class annotation:frank1234,hello
method annotation:frank1234,helloworld annotation methodtype
method annotation parametertype:frank1234,helloworld annotaion parametertype
field annotation:frank1234,helloworld annotation fieldtype

7其他几个注解相关的方法
Class aClass = TheClass.class;
//判断是否有注解
boolean isAnnotation = aClass.isAnnotationPresent(MyAnnotation.class);
MyAnnotation annotation = null;
if(isAnnotation)
//直接获取某类型的自定义注解
annotation = (MyAnnotation)aClass.getAnnotation(MyAnnotation.class);
System.out.print(annotation.name()+","+annotation.value());


8注解的优缺点
优点:
1)减少配置。因为注解的出现就是为了干这个,所以它至少得有这个优点。
2)注解是类型安全的,xml运行时才会发现问题。
3)定义了一种标准的描述元数据的方式。
4) 便于进行重构,可在IDE中直接重构,而无需修改配置。

缺点:
1)跟源代码绑定。如果要修改注解必须的修改源代码,然后重新编译,这点上不如xml配置。
2)比较分散。注解会分散到各个类中,而使用xml配置的话,就统一维护在几个配置文件中。

框架一般这两方式都支持,这个同其他技术一样,没有绝对的好坏,只有适合不适合,不然的话绝对坏的方案就没有存在的必要了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值