5分钟带你入门Java注解annotation

 

包  java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。
接口 java.lang.annotation. Annotation 是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。 
该包同时定义了四个元注解,
Documented
注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中.
Target(作用范围,方法,属性,构造方法等),
用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。
Retention(生命范围,源代码,class,runtime)。
用来声明注解的保留策略,有CLASS、RUNTIME和SOURCE这三种,
分别表示注解保存在类文件、JVM运行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在运行时刻通过反射API来获取到注解的信息。
Inherited : 在您定义注解后并使用于程序代码上时,预设上父类别中的注解并不会被继承至子类别中,
您可以在定义注解时加上java.lang.annotation.Inherited 限定的Annotation,这让您定义的Annotation型别被继承下来

1.作用

(1)生成文档。也是最常见的,常用的有@see @param @return等
(2)替代配置文件。spring 2.5以后开始基于注解开发,现在的框架基本上都用了注解减少配置文件。【spring4.x注解概述】有具体的说明。
(3)编译时进行格式检查。 如@Override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
 

2.自定义注解用法

(1)建一个注解@interface TestA
package com.annotationTest;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR}) 
@Retention(RetentionPolicy.RUNTIME)
public @interface TestA {
    String name();
    int id() default 0;
    Class<Long> gid();
}
(2)写一个类UserAnnotation 来使用@TestA
package com.annotationTest;
import java.util.ArrayList;
import java.util.List;
@TestA(name="type",gid=Long.class) //类成员注解
public class UserAnnotation {

    @TestA(name="param",id=1,gid=Long.class) //类成员注解
    private Integer age ;

    @TestA (name="construct",id=2,gid=Long.class)//构造方法注解
    public UserAnnotation() {
    }

    @TestA(name="public method",id=3,gid=Long.class) //类方法注解
    public void functionA(){
        List list = new ArrayList();
    }
    @TestA(name="protected method",id=4,gid=Long.class) //类方法注解
    public void functionB(){
        List list = new ArrayList();
    }

    @TestA(name="private method",id=5,gid=Long.class) //类方法注解
    public void functionC(){
        List list = new ArrayList();
    }
 }
(3)简单打印出UserAnnotation 类中所使用到的类注解
jdk反射机制
public interface AnnotatedElement {
        boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
        <T extends Annotation> T getAnnotation(Class<T> annotationClass);
        Annotation[] getAnnotations();
        Annotation[] getDeclaredAnnotations();
}
isAnnotationPresent:判断是否标注了指定注解
getAnnotation:获取指定注解,没有则返回null
getAnnotations:获取所有注解,包括继承自基类的,没有则返回长度为0的数组
getDeclaredAnnotations:获取自身显式标明的所有注解,没有则返回长度为0的数组

package com.annotationTest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ParseAnnotation {
    public static void parseTypeAnnotation() throws ClassNotFoundException{
     Class clazz = Class.forName("com.annotationTest.UserAnnotation");
     Annotation[] annotations = clazz.getAnnotations();
     for (Annotation annotation : annotations) {
        TestA testA = (TestA) annotation;
        System.out.println("id = "
                            +testA.id()
                            +"\t name = "
                            +testA.name()
                            +"\t gid = "
                            +testA.gid()
                            );
    }
 }
    private static void parseConstructAnnotation() {
        Constructor[] constructors = UserAnnotation.class.getConstructors();
        for (Constructor constructor : constructors) {
            boolean hasAnnotation = constructor.isAnnotationPresent(TestA.class);
            if (hasAnnotation) {
                TestA annotation = (TestA) constructor.getAnnotation(TestA.class);
                System.out.println("constructor  : "
                                    +constructor.getName()
                                    +"\t id = "
                                    +annotation.id()
                                    +"\t name = "
                                    +annotation.name()
                                    +"\t gid = "
                                    +annotation.gid()
                                    );
            }
        }
    }
    private static void parseMethodAnnotation() {
        Method[] methods = UserAnnotation.class.getDeclaredMethods();         
        for (Method method : methods) {
               /*
             * 判断方法中是否有指定注解类型的注解
             */ 
            boolean hasAnnotation = method.isAnnotationPresent(TestA.class);
            if (hasAnnotation) {
                TestA annotation = method.getAnnotation(TestA.class);
                System.out.println("method : "
                                    +method.getName()
                                    +"\t id = "
                                    +annotation.id()
                                    +"\t name = "
                                    +annotation.name()
                                    +"\t gid = "
                                    +annotation.gid()
                                    );
            }
        }
    }
    public static void main(String[] args) throws ClassNotFoundException {
        parseTypeAnnotation();
        parseConstructAnnotation();
        parseMethodAnnotation();
    }
}
 
 

3.建议

(1) 不要滥用注解。首先强烈建议学习好框架里出现的注解,按照框架规定的方式使用。
(2) 不要滥用注解。平常我们编程过程很少接触和使用注解,只有做设计,且不想让设计有过多的配置时。
(3) 要用好注解,必须熟悉java 的反射机制,从上面的例子可以看出,注解的解析完全依赖于反射。
    
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值