注解的定义:
注解是一种能被添加到java代码中的元数据,类、方法、变量、参数和包都可以用注解来修饰。注解对于它所修饰的代码并没有直接的影响。
元数据定义:
元数据是指用来描述数据的数据,更通俗一点,就是描述代码间关系,或者代码与其他资源(例如数据库表)之间内在联系的数据。对struts来说,元数据指的是struts-config.xml;对hibernate来说就是hbm文件。
注解分为内置注解、自定义注解
内置注解又可以区分为元注解和JDK自带注解
JDK自带注解
@Override:用于标明此方法覆盖了父类的方法
@Deprecated:用于标明已经过时的方法或类
@SuppressWarnnings:用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告
元注解:用于定义注解的注解,@interface上面按需要注解上一些东西,包括@Retention、@Target、@Document、@Inherited四种。
@Retention:用于定义注解的生命周期
@Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码文件中存在,但运行时不会被虚拟机保留
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,而且在运行时会被虚拟机保留,可以通过反射获取到
@Target:是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的。它使用的枚举类型源码如下所示。
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.4.1 @Target
* @jls 4.1 The Kinds of Types and Values
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
当为枚举类型中的Type时该注解可以作用于类,接口,注解,枚举类型
当为枚举类型中的FIELD时该注解可以作用于属性上,包含枚举类型属性
当为枚举类型中的METHOD时该注解可以作用于方法上
当为枚举类型中的PARAMETER时该注解可以作用于方法上对应的形参上
当为枚举类型中的CONSTRUCTOR时该注解可以作用于构造方法上
当为枚举类型中的LOCAL_VARIABLE时该注解可以作用于局部变量上
当为枚举类型中的ANNOTATION_TYPE时该注解可以作用于注解上
当为枚举类型中的PACKAGE时该注解可以作用于Java包(PACKAGE)上
@Documented:是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中。
@Inherited:允许子类继承父类中的注解
下面我们来自定义注解,并获取注解中的内容
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestZH {
String name();
int age();
}
利用反射获取注解内容
public class TestAn{
@TestZH(name="liuhong",age=12)
public static void main(String[] args) throws Exception {
//通过反射获取类
Class<?> forName = Class.forName("com.hongyu.utils.TestAn");
//通过反射获得方法
Method method = forName.getMethod("main", String[].class);
//判断方法上是否存在@TestZH注解
if(method.isAnnotationPresent(TestZH.class)){
//获取方法上对应的注解信息
TestZH annotation = method.getAnnotation(TestZH.class);
//自定义注解有点类似于枚举类型
System.out.println(annotation.name()+" \n "+annotation.age());
}
}
}
以上获取注解内容的输出结果
以上是简单的自定义注解及其注解属性获取方式
其实第三方注解也是自定义注解的一种,下面用Spring的注解源码举例说明
@Controller注解的源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
@RequestMapping的源码
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
因此,第三方注解其实也是自定义注解中的一种。