学习整理——Java注解

注解

注解(也被称为 元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在后续某个时刻非常方便地使用这些数据。注解在Java SE5中引入,在一定程度上是在把元数据与源代码文件结合在一起,而不是保存在外部文档中这一大的趋势之下所催生的。它们可以提供用来完整地描述程序所需的信息,而这些信息是无法用Java来表达的。因此,注解使得我们能够以将由编译器来测试和验证的格式,存储有关程序的的额外信息。注解可以用来生成文件描述符,甚至或是新的类定义,并且有助于减轻编写“样板”代码的负担。


标准注解

Java SE5内置了3种标准注解,定义在java.lang中,所以平时我们不用引入就可以直接引用。

@Override:表示当前的方法定义将覆盖超类中的方法。如果不小心拼错方法或方法参数不一样,编译器就会发出错误提示;

@Deprecated:如果程序员使用了注解为它的元素,那么编译器会发出警告信息。Android开发时一些过时API提示便是使用了该注解;

@SuppressWarnnings:关闭不当的编译器警告信息。开发者不愿看到或确信警告无关紧要时可使用。


元注解

除3种标准注解外,Java还提供了4种元注解,专门负责新注解的创建。开发者可以利用它们来开发自己的注解。

@Target:表示该注解可以用于什么地方,可选ElementType(enum枚举)参数(CONSTRUCTOR:构造器的声明;FIELD:域声明(包括enum实例);LOCAL_VARIABLE:局部变量声明;METHOD:方法声明;PACKAGE:包声明;PARAMETER:参数声明;TYPE:类、接口(包括注解类型)或enum声明);

@Retention:表示需要在什么级别保存该注解信息。可选RetentionPolicy(enum)参数(SOURCE:注解将被编译器丢弃;CLASS:注解在CLASS文件中可用,但会被VM丢弃;RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息);

@Doucmented:将此注解包含在Javadoc中;

@Inherited:允许子类继承父类的注解。


注解定义

注解的定义与接口的定义类似,需要在interface前加上@以表示注解,同时加上元注解用以创建。一个简单的注解实例如下:

package cc.appweb.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
public @interface AnnotationTest{
	// nothing
}

上述定了一个AnnotationTest的注解,但里面没有元素。没有元素的注解称为 标记注解

有些注解需要加入元素以让其实现更加灵活,比如有一些类需要为它的方法进行编号,如1、2、3等,这时可以定义一些元素。

package cc.appweb.annotation;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodID{
	public int id();  // method id
	public String description() default "no description";  // description
}
应用时,可以这样标注。

import cc.appweb.annotation.MethodID;


public class JMain {
	
	@MethodID(id=0)
	public int getId(){
		return 1;
	}
	
	@MethodID(id=1,description="get the String ID")
	public String getStringID(){
		return "1";
	}
}
这样开发人员可以很清晰地知道该函数是什么阶段引入的。注解的元素也可以设置默认值,已设置默认值的元素在应用时可以缺省,如description。

注解的元素可用的类型如下:

1.所有的基本类型

2.String

3.Class

4.enum

5.Annotation

6.以上类型的数组


注解处理器

如果没有用来读取注解的工具,那注解不会比注释更有用。编译器级别的支持,加上Annotation API和Java 反射API能够使得注解在一些场合非常好用,适合程序员(Spring框架也有用到注解的地方)。

以下是一个简单的注解处理器,将类中用到注解的方法找出来,并且输出其必要信息。

import java.lang.reflect.Method;
import cc.appweb.annotation.MethodID;

public class JMain {
	
	public static void main(String[] args){
		Class<JMain> cl = JMain.class;
		for(Method m : cl.getDeclaredMethods()){
			MethodID mID = m.getAnnotation(MethodID.class);
			if(mID != null){
				// 方法被标记
				// 做处理
				System.out.println(
						"Method name:" + m.getName() + "\n" +
						"Method ID:" + mID.id() + "\n" +
						"Method description:" + mID.description()		
						);
			}
		}
	}
	
	@MethodID(id=0)
	public int getId(){
		return 1;
	}
	
	@MethodID(id=1, description="get the String ID")
	public String getStringID(){
		return "1";
	}
}
输出:

Method name:getId
Method ID:0
Method description:no description
Method name:getStringID
Method ID:1
Method description:get the String ID

可以看到,注解和注解处理器的结合可以用于自动生成描述文本,或者配置文件等,也可以自动生成SQL语句或者http上的RequestMapping,以下不详细介绍。


附录

三个标准注解的定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

四个元注解的定义

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

本文主要参考《Java编程思想》。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值