java中的注解
一、概念
注解是插入到源代码中的标记,并且可以使用其他工具(程序)对其进行处理。
这些工具可以在源码层次上进行操作,或者可以处理 由编译器放置了注解的类文件(.class)。
注解是源代码的一部分,但不会改变程序的编译方式,编译器对于包含注解和不包含注解的代码会生成相同的虚拟机指令。
二、应用场景及好处
应用广泛,很多工具或者说框架的编写者都会让使用者采用注解的形式,例如测试框架JUnit等
对于处理工具/框架的使用者来说,注解语法更加简洁友好。
三、注解分类
1、 元注解:系统已经定义好的,注解在注解接口上
(1) @Target :限制注解可以应用到哪些目标元素,元素类型是ElementType枚举型
@Target注解的元素类型
元素类型(在ElementType中定义) 注解应用场合
ANNOTATION_TYPE 注解类型声明
PACKAGE 包
TYPE 类
METHOD 方法
CONSTRUCTOR 构造方法
FIELD 成员变量
PARAMETER 方法或构造方法的参数
LOCAL_VARIABLE 局部变量
(2) @Retention :指定注解保存的时间
@Retention的保留策略
保留规则 描述
SOURCE 源文件(.java)
CLASS 包括在类文件中(.class),但是虚拟机不需要将它们载入
RUNTIME 包括在类文件中(.class),并由虚拟机载入。通过反射机制可获得定义的注解
(3) @Documented : 是否将注解保存到javadoc中
(4) @Inherited : 声明注解可以被子类继承
2、标准注解
(1) 用于编译的注解
(2) 用于资源管理的注解
3、自定义注解
四、定义注解
每个注解都必须通过一个注解接口进行定义,这些接口中的方法与注解中的元素(属性)相对应。
语法:
访问修饰符 @interface 注解名{
方法返回值 方法名() default 元素(属性)的默认值;
//属性值类型 属性名 属性的默认值
}
例如,我们写一个工具来在控制台打印某个类的详细信息,来模拟某些API框架。
在定义注解的时候,我们有必要思考的有:注解的功能、注解的作用在哪个位置、注解中有什么元素(属性)及元素的类型。
定义描述类的注解接口:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE) //限定@API注解只能用于类型上
@Retention(RetentionPolicy.RUNTIME) //保留在运行时,为了方便处理程序能通过反射机制获得@API注解
public @interface API {
/**
* 类描述
* @return
*/
String value() default "";
}
定义描述对象字段的注解接口:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Property {
/**
* 字段类型
* @return
*/
String type() default "";
/**
* 字段名字
* @return
*/
String name() default "";
/**
* 字段默认值
* @return
*/
String defaultValue() default "";
/**
* 字段描述
* @return
*/
String description() default "";
}
注意事项:
1、注解接口中的方法不能有形参
2、方法的返回值(元素类型)可以是基本类型、String、Class、枚举类型、注解类型和它们的数组类型
3、default是关键字,用来指定元素的默认值,默认值不能设置为null,可以设置成""或者"none"或者Void.class
4、@interface声明创建了一个真正的java接口。处理注解的工具将接收那些实现了这个注解接口的对象。
四、使用注解
在使用注解时,应该考虑的问题有:注解有哪些元素、注解的功能、注解作用在哪些位置上。
在java中,注解是当作一个修饰符来使用的,使用@注解名字
例如,用户类对象
@API(“用户”)
public class User {
@Property(type="Number",description="账号")
private Integer id = 1;
@Property(description="用户名")
private String name = "Herrona";
@Property(description="密码")
private String pwd = "1234";
@Property(type="Number",description="年龄")
public int age = 20;
}
使用注解时的注意事项:
(1) 元素没有顺序
(2) 如果只使用value属性,则可以省略value属性的名字
(3) 如果不使用注解中的属性,则可以省略注解括号,这样的注解称为标记注解
五、注解处理工具(注解处理程序)
前面说过,注解通过注解接口来定义的,接口只是抽象的描述和约定,并不会帮我们实现功能。
所以我们还必须写注解处理程序来实现我们需要的功能。
处理程序可以通过反射机制获得类、字段、方法和注解等的信息。
import java.lang.reflect.Field;
/**
注解处理类
@author Herrona
*/
public class ApiPrinter {/**
- 在控制台打印成表格
- @param obj
- @throws IllegalAccessException
- @throws IllegalArgumentException
*/
public static void print(Object obj) throws IllegalArgumentException, IllegalAccessException {
Class<?> c = obj.getClass();
API api = c.getAnnotation(API.class);
if (api != null) {
}System.out.printf("%s <%s> 详情:\n",api.value(),c.getTypeName()); System.out.println("--------------------------------------------------------------"); System.out.printf("字段名\t\t字段类型\t\t默认值 \t\t描述\n"); System.out.println("--------------------------------------------------------------"); // 遍历属性 for (Field f : c.getDeclaredFields()) { // 获得属性上的Property注解对象 Property p = f.getAnnotation(Property.class); // 如果该属性使用了Property注解对象 if (p != null) { f.setAccessible(true); String name = p.name(); String type = p.type(); String defaultType = p.defaultValue(); String desc = p.description(); if(name.equals("")) name = f.getName(); if(type.equals("")) type = f.getType().getSimpleName(); if(defaultType.equals("")) defaultType = f.get(obj).toString(); System.out.printf("%s\t\t%s\t\t%s\t\t%s", name, type,defaultType,desc); System.out.println(); } } System.out.println("--------------------------------------------------------------");
}
}
六、测试 六、测试
调用处理程序的方法,在控制台打印对象信息。
public class Test {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
ApiPrinter.print(new User());
}
}
相关文章
发表评论
评论列表
- 这篇文章还没有收到评论,赶紧来抢沙发吧~