java之注解Annotation

什么是java注解

java注解是java代码的元数据,用来声明或者配置java代码,而不影响java代码的正常的运行逻辑。java注解的本质是一种特殊类型的接口,该接口继承Annotation接口。

注解的分类

java注解分为两种类型:元注解和自定义注解。

元注解

用来注解注解的注解,主要包含四个,@Target,@Retention,@Documented,@Inherited。

@Documented

//没有任何方法,用来生成文档,javadoc Test.java
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

@Target

// 用来定义注解使用的地方
@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();
}

注解几乎可以用到java的任何地方:

public enum ElementType {
TYPE,  //类,接口,或者注解上
    FIELD, //字段上
    METHOD,  //方法上
    PARAMETER, //参数上
    CONSTRUCTOR, //构造函数上
    LOCAL_VARIABLE, //局部变量上
    ANNOTATION_TYPE, //注解上
    PACKAGE,  //包上
    TYPE_PARAMETER //类型参数上
    TYPE_USE  //类型上
}

@Retention

@Retention定义了注解的保留时间

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

RetentionPolicy包括,源码,字节码还有运行时:

public enum RetentionPolicy {
    //源码将在编译过后丢弃该注解,注解仅仅在源码中保留
    SOURCE,
    
    //源码能保留至字节码,即字节码中保留着注解的信息,该信息不会被jvm加载
    //当注解未定义retention,默认就是class
    CLASS, 
    
    //java运行期,注解依然存在,可以被反射机制获取
    //例如SpringMvc中的@Controller@Autowired@RequestMapping
    RUNTIME 
}

@Inherited

可以让注解被继承,但这并不是真的继承,只是通过使用@Inherited,可以让子类Class对象使用getAnnotations()获取父类被@Inherited修饰的注解

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoInherited {
}

@YesInherited 
class Parent1{ }

class Child1 extends A{ }

@NoInherited 
class Parent2{ }

class Child2 extends Parent2{ }

public class Test{

    public static void main(String... args){
        // 能得到注解YesInherited
        Parent1 instance1=new Child1();
        System.out.println(Arrays.toString(instance1.getClass().getAnnotations()));

        // 不能得到注解NoInherited
        Parent2 instance2 = new Child2 ();
        System.out.println(Arrays.toString(instance2.getClass().getAnnotations()));
    }

}

自定义注解

如下自定义一个注解@DBTable,
该注解用于修饰类,接口或者注解上,
该注解可以存活到运行期

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
    String name() default "";
}

然后,我们可以按如下方式使用注解,其中name就是方法的名称。
如果注解内的方法名有一个为value,在使用该注解的时只想指定value,
此时不需要写key,即@DBTable(“MEMBER”)即可,省略value=

@DBTable(name = "MEMBER")
public class Member {
}

注解方法可以使用default xxx表明该方法的返回默认值为xxx。
返回的数据类,可以有如下6大类:

1. 所有基本类型(int,float,boolean,byte,double,char,long,short)
2. String
3. Class
4. enum
5. Annotation
6. 上述类型的数组

注意注解方法的值,必须要确定,即必须要赋一个合法默认值。

java内置注解

@Override:用于标明此方法覆盖了父类的方法,源码如下

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

@Deprecated:用于标明已经过时的方法或类,源码如下

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

@SuppressWarnnings:用于有选择的关闭编译器对类、方法、成员变量、变量初始化的警告,其实现源码如下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
//数组可以包含如下值
deprecation:使用了不赞成使用的类或方法时的警告;
unchecked:执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型; 
fallthrough:当 Switch 程序块直接通往下一种情况而没有 Break 时的警告;
path:在类路径、源文件路径等中有不存在的路径时的警告; 
serial:当在可序列化的类上缺少 serialVersionUID 定义时的警告; 
finally:任何 finally 子句不能正常完成时的警告; 
all:关于以上所有情况的警告

注解与反射

java可以使用反射的方式在java程序运行时动态的获取注解信息。java用Annotation来代表注解,Annotation是一个接口,是所有注解的父类,获取java的注解,实际上是获取了一个实现该子接口的类实例,相当于内部匿名类。

AnnotatedElement可以通过反射技术获取注解信息。AnnotationElement主要代表如下元素:

Class:类的Class对象定义   
Constructor:代表类的构造器定义   
Field:代表类的成员变量定义 
Method:代表类的方法定义   
Package:代表类的包定义

下面是AnnotatedElement中相关的API方法,以上5个类都实现以下的方法:

// 获取指定类型的注解
getAnnotation(Class<A> annotationClass)
// 获取所有注解,包含继承的
getAnnotations()
// 查看指定类型的注解是否存在
isAnnotationPresent(Class<? extends Annotation> annotationClass)
// 返回直接修饰该元素的注解
getDeclaredAnnotations()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值