Java语言十五讲——第一讲 Annotation

第一讲 Annotation

在编Java程序的时候,我们经常会碰到annotation。比如:

@Override 我们在子类继承父类的时候,会经常用到这个annotation。它告诉编译器这个方法是override父类的方法的。

@WebServlet("/myservlet") 在进行Web开发的时候,我们用这个annotation表示这个类是一个servlet。Web容器会识别这个annotation,在运行的时候调用它。

很多人说annotation是注释,初看起来有一点像,它对程序的编写和编译似乎没有什么影响,只是给人看的一个对程序的附注。从这点上,确实有一点像注释。不过,它跟注释不同的是,它会影响程序的运行。比如,上面提到的@Override,如果没有override父类的方法,编译器会给出错误提示;再比如,上面的@WebServlet,如果没有这个注解,程序是运行不起来的。

由此看来,annotation不是注释,注释是给人看的,并不影响程序的编译和运行时候的行为。annotation其实不是给人看的,那么它是给谁看的呢?它被设计出来,用于给另外的程序看的,比如编译器,比如框架,比如Web容器。

这些外在的程序通过某种方式查看到这些annotation后,就可以采取相应的行为。具体解释一下。

假如我们要做一个Web容器,类似于Tomcat这种的。它的一个基本功能就是加载servlet。按照JavaEE的规范,容器需要管理servlet的生命周期,第一件事情就是要识别哪些类是servlet。那么,容器启动的时候,可以扫描全部类,找到包含@WebServlet注解的,识别它们,然后加载它们。那么,这个@WebServlet注解就是在运行时起作用的,Java里面把它的作用范围规定为RUNTIME。

再看@Override,这个是给编译器看的,编译程序读用户程序的源代码,识别出有override注解的方法,就去检查上层父类相应方法。这个@Override注解就是在编译的时候起作用的,编译之后,就不存在了。Java里面把它的作用范围规定为SOURCE。

类似的注解还有@Test,程序员写好了程序,想交给测试框架去测试自己写的方法,就可以用这个注解。测试框架会读取源代码,识别出有@Test注解的方法,就可以进行测试了。

平时,我们可能都是用别人提供的注解来工作。注解的使用其实相当简单,我不打算在讲座中特意讲解,因为这是一个进阶的讲座。我们要研习的东西更加深一点。

接下来,我们自己动手做一个注解看看效果加深理解。

我们想做的例子是一个运行时框架加载别的客户类,并运行其中的初始化方法。作为框架,我们可以提供一个@InitMethod注解给客户程序员。客户类代码如下:

public class InitDemo {
	@InitMethod
	public void init(){
		System.out.println("init ...");
	}
}

客户类程序员在init()方法上标注了@InitMethod注解,声明这就是本类的初始化方法。框架程序识别它,并调用它。

接下来我们看怎么提供这个注解的实现。代码如下:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InitMethod {
}

第一次看到这个注解的实现的时候,人们都会大吃一惊,觉得很像是在定义一个 interface。的确很像,Java5之后,提供了这样的手段,让人定义注解。上面就声明了有一个叫InitMethod的注解,它是修饰方法的,在运行时可见。

问题来了,上面这一段并不是真正的实现,只是一个定义或者声明。那真正的实现怎么做呢?这些当然要定义者来提供实现的。我们作为框架程序的作者,有责任实现它,代码如下:

public class InitProcessor {
	public static void main(String[] args) 
        throws ClassNotFoundException, IllegalAccessException,IllegalArgumentException,InvocationTargetException, InstantiationException {
		Class<?> clazz = Class.forName("InitDemo");
		Method[] methods = clazz.getMethods();
		if(methods!=null){
			for(Method method:methods){
				boolean isInitMethod = method.isAnnotationPresent(InitMethod.class);
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值