访问注解(annotation)的几种常见方法

java的注解处理器类主要是AnnotatedElement接口的实现类实现,为位于java.lang.reflect包下。由下面的class源码可知AnnotatedElement接口是所有元素的父接口,这时我们通过反射获得一个类的AnnotatedElement对象后,就可以通过下面表格的几个方法,访问Annotation信息。

public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, AnnotatedElement{
}

java.lang.Class中有关getDeclared**和get**的方法以getDeclaredMethods和getMethods为例说明:

getDeclaredMethod(s):返回自身类的所有公用(public)方法包括私有(private)方法,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

返回数组中的元素没有排序,也没有任何特定的顺序。如果该类或接口不声明任何方法,或者此 Class 对象表示一个基本类型、一个数组类或 void,则此方法返回一个长度为 0 的数组。

类初始化方法 <Constructor> 不包含在返回数组中。如果该类声明带有相同参数类型的多个公共成员方法,则它们都包含在返回的数组中。

getMethod(s):返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。

数组类返回从 Object 类继承的所有(公共)member 方法。

返回数组中的元素没有排序,也没有任何特定的顺序。如果此 Class 对象表示没有公共成员方法的类或接口,或者表示一个基本类型或 void,则此方法返回长度为 0 的数组。
总之:getDeclaredMethods的关键词是:自身,所有方法,不继承而getMethods的关键词是public 继承

getDeclaredField(s)和getField(s)同上。

getDeclaredAnnotation(s):返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

getAnnotation(s):返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

getDeclaredAnnotations得到的是当前成员所有的注释,不包括继承的。而getAnnotations得到的是包括继承的所有注释。

关键在于继承的问题上,getDeclaredAnnotations和getAnnotations是否相同,就在于父类的注解是否可继承,这可以用sun.reflect.annotation.AnnotationType antype3=AnnotationType.getInstance(Class.forName(annotationtype_class(example:"javax.ejb.Stateful")).isInherited())来判定,如果为true,说明可以被继承则存在与getAnnotations之中而不在getDeclaredAnnotations之中,否则,也不存在与getannnotations中,因为不能被继承。

举例说明:

首先,创建自定义注解和创建一个接口相似,但是注解的interface关键字需要以@符号开头。我们可以为注解声明方法。

注意事项:

  • 注解方法不能带有参数;
  • 注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;
  • 注解方法可以有默认值;
  • 注解本身能够包含元注解,元注解被用来注解其它注解。
package com.cj.Annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
    String author() default "Pankaj";
    String date();
    int revision() default 1;
    String comments();
}

这里有四种类型的元注解:

1. @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。

2. @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。

3. @Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。

4.@Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME。

Java内建注解

Java提供了三种内建注解。

1. @Override——当我们想要复写父类中的方法时,我们需要使用该注解去告知编译器我们想要复写这个方法。这样一来当父类中的方法移除或者发生更改时编译器将提示错误信息。

2. @Deprecated——当我们希望编译器知道某一方法不建议使用时,我们应该使用这个注解。Java在javadoc 中推荐使用该注解,我们应该提供为什么该方法不推荐使用以及替代的方法。

3. @SuppressWarnings——这个仅仅是告诉编译器忽略特定的警告信息,例如在泛型中使用原生数据类型。它的保留策略是SOURCE(译者注:在源文件中有效)并且被编译器丢弃。

 来看一个java内建注解的例子参照上边提到的自定义注解。

package com.cj.Annotation;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class AnnotationExample {
    @Override
    @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
    public String toString() {
        return "Overriden toString method";
    }

    @Deprecated
    @MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
    public static void oldMethod() {
        System.out.println("old method, don‘t use it.");
    }

    @SuppressWarnings({ "unchecked", "deprecation" })
    @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
    public static void genericsTest() throws FileNotFoundException {
        List l = new ArrayList();
        l.add("abc");
        oldMethod();
    }

}

 Java注解解析
我们将使用反射技术来解析java类的注解。那么注解的RetentionPolicy应该设置为RUNTIME否则java类的注解信息在执行过程中将不可用那么我们也不能从中得到任何和注解有关的数据。 

package com.cj.Annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationParsing {

    public static void main(String[] args) {
        try {
            ClassLoader loader =AnnotationParsing.class.getClassLoader();
           // Class src = loader.loadClass("com.cj.Annotation.AnnotationParsing");
            Class className=loader.loadClass("com.cj.Annotation.AnnotationExample");
            //Method[] methodss=src.getMethods();
            Method[] methods = className.getMethods();
            for (Method method : methods) {
                // checks if MethodInfo annotation is present for the method
                if (method.isAnnotationPresent(com.cj.Annotation.MethodInfo.class)) {
                    try {
                        // iterates all the annotations available in the method
                        for (Annotation anno : method.getDeclaredAnnotations()) {
                            System.out.println("Annotation in Method "+ method + " : " + anno);
                        }
                        MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
                       // if (methodAnno.revision() == 1) {
                            System.out.println("Method with revision no 1 = "+ methodAnno);
                        //}

                    } catch (Throwable ex) {
                        ex.printStackTrace();
                    }
                }
            }
        } catch (SecurityException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

}

  

参考网址:

https://my.oschina.net/itgaowei/blog/1602277

http://blog.sina.com.cn/s/blog_605f5b4f0100i77k.html

http://www.importnew.com/17413.html

原文地址:https://www.cnblogs.com/alice-cj/p/10388624.html

时间: 2024-10-17 00:10:02

访问注解(annotation)的几种常见方法的相关文章

Python爬虫突破封禁的6种常见方法

转 Python爬虫突破封禁的6种常见方法 2016年08月17日 22:36:59 阅读数:37936 在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于用"网络数据采集",有时会把网络数据采集程序称为网络机器人(bots).最常用的方法是写一个自动化程序向网络服务器请求数据(通常是用HTML表单或其他网页文件),然后对数据进行解析,提取需要的信息. 本文假定读者已经了解如何用代码来抓取一个远程的URL,并具备表单如何提交及JavaScrip

性能测试的几种常见方法

性能测试的几种常见方法(转) 负载测试:负载测试是用户观点的测试行为.简单说来就是负载测试就是让系统在一定得负载压力下进行正常的工作,观察系统的表现能否满足用户的需求. 用户的需求从何而来?需求分析--特指性能测试的需求分析.由此看来需求分析是相当重要的. 负载测试是站在用户的角度去观察在一定条件下软件系统的性能表现. 负载测试的预期结果是用户的性能需求得到满足.此指标一般体现为响应时间.交易容量.并发容量.资源使用率等. 负载测试也是最常用的性能测试方法,因此也有不少人将负载测试混淆为性能测试

内存数据持久化的两种常见方法

内存数据持久化的两种常见方法: 1.将内存数据定期dump到磁盘 优点:效率高,操作简便 缺点:会损失部分数据 2.利用类似于mysql的binlog日志的方式,记录更新操作,需要时回放数据 优点:可保证数据完整性 缺点:会损失部分性能,实现稍微复杂点 redis实现了这两种方式

数组去重的几种常见方法?

数组去重的几种常见方法 一.简单的去重方法 // 最简单数组去重法 /* * 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中 * IE8以下不支持数组的indexOf方法 * */ function uniq(array){ var temp = []; //一个新的临时数组 for(var i = 0; i < array.length; i++){ if(temp.indexOf(array[i]) == -1){ temp.push(array[i]); } } retur

JS数组去重的几种常见方法

JS数组去重的几种常见方法 一.简单的去重方法 // 最简单数组去重法 /* * 新建一新数组,遍历传入数组,值不在新数组就push进该新数组中 * IE8以下不支持数组的indexOf方法 * */ function uniq(array){ var temp = []; //一个新的临时数组 for(var i = 0; i < array.length; i++){ if(temp.indexOf(array[i]) == -1){ temp.push(array[i]); } } ret

黑盒技术生成测试用例几种常见方法

因为实验还没做,所以无法写实验报告.在这里我将简述几种常见的黑盒测试方法. 黑盒测试,又称功能测试或者数据驱动测试.是把测试对象看作一个黑盒子.利用黑盒测试法进行动态测试时,需要测试软件产品的功能.不需要测试软件产品的内部结构和处理过程.   采用黑盒技术设计的测试用例方法有: 等价类划分方法 边界值分析 错误推测 因果图方法 判定表驱动分析方法 正交实验设计方法 功能图分析方法 等价类划分: 把所有可能的输入数据,即程序的输入域划分成若干部分,然后从每一个子集中选取少数具有代表性的数据作为测试

为何大量网站不能抓取?爬虫突破封禁的6种常见方法

在互联网上进行自动数据采集(抓取)这件事和互联网存在的时间差不多一样长.今天大众好像更倾向于用“网络数据采集”,有时会把网络数据采集程序称为网络机器人(bots).最常用的方法是写一个自动化程序向网络服务器请求数据(通常是用 HTML 表单或其他网页文件),然后对数据进行解析,提取需要的信息. 本文假定读者已经了解如何用代码来抓取一个远程的 URL,并具备表单如何提交及 JavaScript 在浏览器如何运行的机制.想更多了解网络数据采集基础知识,可以参考文后的资料. 在采集网站的时会遇到一些比

vue中this.$router.push()路由传值和获取的两种常见方法

1.路由传值   this.$router.push() (1) 想要导航到不同的URL,使用router.push()方法,这个方法会向history栈添加一个新纪录,所以,当用户点击浏览器后退按钮时,会回到之前的URL (2)当点击 <router-link> 时,这个方法会在内部调用,即点击 <router-link :to="..."> 等同于调用 router.push(...) a)      声明式:<router-link :to=&quo

藏文件的两种常见方法(隐写术)

1.利用ADS::$DATA(windows文件流绕过)也就是利用了NTFS交换数据流(ADS),ADS是NTFS磁盘格式的一个特性,在NTFS文件系统下,每个文件都可以存在多个数据流.通俗的理解就是其它文件可以“寄宿”在某个文件身上,而在资源管理器中却只能看到宿主文件,找不到寄宿文件.::DATA就是默认不修改文件流.利用windows特性,可在后缀名中加‘::DATA绕过. 可以用NTFS磁盘格式的这个特性试着隐藏自己的文件. 先打开当前文件夹的cmd,这里我在桌面上新建了个文件夹 打开该文