Java基础:注解

使用注解

在日常开发中,我们随处可以看到注解的身影,比如@Override、@SupressWarnings等等。使用各种框架比如SpringMVC、Struts2时,也会大量用到注解取代XML进行配置工作。请看下面的代码:

<bean id="testService" class="com.test.service.TestService">
    <property name="testDao" ref="testDao" />
</bean>

如果不使用注解,我们要配置一个Service,就需要在spring-servlet.xml中配置这样一段XML代码,但又了注解,我们就可以很轻松的在Java类中完成这个配置:

package com.test.service;

@Service(value = "testService")
public class TestService{
    
    @Autowired
    private TestDao testDao;
}

这里可以看出注解的好处,我们无需在完成一个类的编码后,再转移到配置文件里进行配置工作,毕竟这个转移过程会分散我们的注意力,放大犯错的可能。

仔细观察上面的注解,可以看到使用注解是以一个@开头,然后是注解的名称。紧随其后的是这个注解的配置参数,以键值对的形式出现。当然,如果这个注解只有一个配置参数,可以只写配置的值,比如@Service("testService")。

自定义注解

大部分时间,我们只需要学会使用注解,知道如何从源码或文档中查找注解的配置方法即可。但如果我们需要进行一些比较通用的功能设计,可能就需要实现自己的注解。

Java中注解定义和接口类似,下面是一个简单的例子:

package com.java.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 自定义的注解
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
    public String value() default "";
}

上面这段代码自定义了一个注解MyAnnotation。定义注解的关键字是@interface ,注解中每一个方法都是一个配置参数。与接口不同的是,注解的方法可以提供一个默认值,即如果在使用注解时没有提供配置参数值,则这个注解以默认值为其配置值。

定义注解时,通常会用到@Retention注解和@Target注解,它们都是元注解,用于声明注解本身的行为。@Retention用于声明定义的注解的保留策略,通过查看JDK文档或Retention源码可以发现,其配置参数类型为RetentionPolicy,RetentionPolicy是枚举类型,有三种不同取值,分别为CLASS、RUNTIME、SOURCE。这三种取值分别表示注解会保存在类文件、JVM运行时、JAVA源代码中。但是只有取值为RUNTIME时,我们才能够在程序运行时,通过反射获取注解的信息,进而使用注解完成功能。

@Target注解用于声明当前定义的注解可以应用于哪些类型的元素上,配置参数类型为ElementType,也是枚举类型,取值有TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE等八种。每一个取值意味着该注解可以被应用在某个具体位置,比如上面的注解@MyAnnotation,它的@Target配置参数为ElementType.Type,那么我们就只能将@MyAnnotation应用在类、接口(包括注解)或者是枚举类型声明。如下:

@MyAnnotation
public class MyClass{}

@MyAnnotation
public interface MyInterface{}

@MyAnnotation
public @interface MyAnnotationTest{}

@MyAnnotation
public enum MyEnum{}

以上对@MyAnnotation的使用都是没有问题的,但如果是下面的情况,则是错误的使用方式:

public class Test{
    @MyAnnotation
    private Integer num;
}

public class Demo{
    @MyAnnotation
    public void execute(){
        // ...
    }
}

其余诸如FIELD表示成员变量,METHOD表示成员方法,PARAMETER表示方法参数等等,基本上都能见文知意。

和@Retention、@Target类似,@Documented也是一个元注解,它的作用是指示这个注解需要被javadoc工具记录到问的那个中去。如果没有指示这个注解,默认情况下javadoc生成的文档是不会包含关于这个注解的信息的。

获取注解信息

对于注解,我们最关注肯定还是其配置参数的值。下面是一段测试代码,演示如何获取注解中配置参数的取值:

package com.java.annotation;

@MyAnnotation("The annotation setting vlaue")
public class AnnotationTest {
    public static void main(String[] args) {
	MyAnnotation annotation = AnnotationTest.class.getAnnotation(MyAnnotation.class);
	System.out.println(annotation.value()); // result : 'The annotation setting vlaue'
    }
}

上面是获取标记在类型上的注解,如果是获取成员方法上的注解,则可以通过以下方法:

Method[] methods = AnnotationTest.class.getMethods();
for(Method m : methods){
    MyAnnotation ma = m.getAnnotation(MyAnnotation.class); // 获取成员方法注解
    System.out.println(ma.value()); // 注意:ma可能为null,报NPE
    
    // m.getParameterAnnotations(); // 获取函数的参数注解
}

同样,我们还可以获取标记在成员变量上的注解:

Field[] fields = AnnotationTest.class.getFields();
for(Field f : fields){
    MyAnnotation ma = f.getAnnotation(MyAnnotation.class); // 获取成员变量上的注解
}

总结

我们在使用SpringMVC时,大量使用注解都会觉得很自然。但真的要自己定义注解并应用到项目中,就不是这么简单的一件事了。上面关于获取注解信息部分,只是简单介绍了如果通过代码获取注解的配置参数,但看上去用处并不大。只有经过严格设计,巧妙运用注解,才能真正发挥注解的作用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值