在我们使用Spring 和 Mybatis 的时候难免会使用到注解。但是注解是什么呢?个人认为是对类或者方法进一步进行一些描述。就好像将一个Java对象和类、方法、字段进行了绑定。
首先我们来看看Java自带的一些注解吧。
Java自带注解
@Override : 必须被覆盖的方法
@Deprecated : 被废弃的方法
@SuppressWarnings : 忽略警告
注解的分类
- 源码注解: 注解只存在于源码中
- 编译注解: 注解只存在与源码和class文件中
- 运行注解: 注解存在于运行期,还会影响运行
自定义注解
语法:
public @interface AnnonationName{
public String fieldName() default "";
}
- 使用@interface关键字定义注解
- 成员以无参数无异常的方式声明
- 使用default为成员指定默认值
- 成员的类型是受限制的:只能是基本数据类型,String,Class,Annotation,Enumration
- 如果注解只有一个成员,成员名必须是value(),使用时可以忽略成员名=
- 注解可以没有成员,没有注解的成员叫做标识注解
元注解
元注解是注解的注解,用来描述注解
- Target
表示注解的作用域
- 构造方法:CONSTRUCTOR
- 字段声明:FIELD
- 局部变量声明:LOCAL_VARIABLE
- 方法声明:METHOD
- 包声明:PACKAGE
- 参数声明:PARAMETER
- 类接口:TYPE
完整语法为:
@Target({ElementType.METHOD, ElementType.TYPE})
- Retention
- SOURCE(只在源码显示,编译时会丢弃)
- CLASS(编译时会记录到class中,运行时会丢弃)
- RUNTIME(运行时存在,可以通过反射读取)
完整语法为:@Retention(RetentionPolicy.RUNTIME)
- Inherited
是标识型的元注解.例子中的注解表示允许子类继承 - Documented
表示生成javadoc时会包含注解信息.
注解的使用
使用注解的语法为:
@<注解名>(<成员名1>=<成员值1>,<成员名2>=<成员值2>,...)
得到注解
API:
getAnnotations(): 返回该元素的所有注解,包括没有显式定义该元素上的注解。
isAnnotationPresent(annotation): 检查传入的注解是否存在于当前元素。
getAnnotation(class): 按照传入的参数获取指定类型的注解。返回null说明当前元素不带有此注解。
例子
注解类
package com.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAnnotation {
public String value() default "ClassName";
}
package com.annotation;
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 FiledAnnotation {
public String value() default "";
}
package com.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 MethodAnnotation {
public String value() default "methodName";
}
使用注解
package com.annotation;
@ClassAnnotation(value="StudentBean is my name")
public class StudentBean {
@FiledAnnotation(value="张三")
public String name;
@MethodAnnotation(value="this is the only method")
public void saySomeThing(){
}
}
测试
package com.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class test {
public static void main(String[] args) {
StudentBean student = new StudentBean();
Class clazz = student.getClass();
//获取类的注解
ClassAnnotation classAnnotation = (ClassAnnotation) clazz.getAnnotation(ClassAnnotation.class);
System.out.println(classAnnotation.value());
//获取方法注解
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println(methods[i].getAnnotation(MethodAnnotation.class).value());
}
//获取字段的注解
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getAnnotation(FiledAnnotation.class).value());
}
}
}
测试结果
StudentBean is my name
this is the only method
张三