zoukankan      html  css  js  c++  java
  • Java注解教程:自定义注解示例,利用反射进行解析

    Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响。在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解。

    注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring。注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效。

    在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多功能,它不仅包含元数据,还能作用于运行期,注解解析器能够使用注解决定处理流程。举个例子,在Jersey webservice中,我们在一个方法上添加了PATH注解和URI字符串,在运行期,jersey会对其进行解析,并决定作用于指定URI模式的方法。

    在Java中创建自定义注解

    创建自定义注解与编写接口很相似,除了它的接口关键字前有个@符号。我们可以在注解中定义方法,先来看个例子,之后我们会继续讨论它的特性。

     1 package com.journaldev.annotations;
     2  
     3 import java.io.FileNotFoundException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6  
     7 public class AnnotationExample {
     8  
     9     public static void main(String[] args) {
    10     }
    11  
    12     @Override
    13     @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
    14     public String toString() {
    15         return "Overriden toString method";
    16     }
    17  
    18     @Deprecated
    19     @MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
    20     public static void oldMethod() {
    21         System.out.println("old method, don't use it.");
    22     }
    23  
    24     @SuppressWarnings({ "unchecked", "deprecation" })
    25     @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
    26     public static void genericsTest() throws FileNotFoundException {
    27         List l = new ArrayList();
    28         l.add("abc");
    29         oldMethod();
    30     }
    31  
    32 }
    • 注解方法不能有参数。
    • 注解方法的返回类型局限于原始类型,字符串,枚举,注解,或以上类型构成的数组。
    • 注解方法可以包含默认值。
    • 注解可以包含与其绑定的元注解,元注解为注解提供信息,有四种元注解类型:

    1. @Documented – 表示使用该注解的元素应被javadoc或类似工具文档化,它应用于类型声明,类型声明的注解会影响客户端对注解元素的使用。如果一个类型声明添加了Documented注解,那么它的注解会成为被注解元素的公共API的一部分。

    2. @Target – 表示支持注解的程序元素的种类,一些可能的值有TYPE, METHOD, CONSTRUCTOR, FIELD等等。如果Target元注解不存在,那么该注解就可以使用在任何程序元素之上。

    3. @Inherited – 表示一个注解类型会被自动继承,如果用户在类声明的时候查询注解类型,同时类声明中也没有这个类型的注解,那么注解类型会自动查询该类的父类,这个过程将会不停地重复,直到该类型的注解被找到为止,或是到达类结构的顶层(Object)。

    4. @Retention – 表示注解类型保留时间的长短,它接收RetentionPolicy参数,可能的值有SOURCE, CLASS, 以及RUNTIME。

    Java内置注解

    Java提供3种内置注解。

    1. @Override – 当我们想要覆盖父类的一个方法时,需要使用该注解告知编译器我们正在覆盖一个方法。这样的话,当父类的方法被删除或修改了,编译器会提示错误信息。大家可以学习一下为什么我们总是应该在覆盖方法时使用Java覆盖注解

    2. @Deprecated – 当我们想要让编译器知道一个方法已经被弃用(deprecate)时,应该使用这个注解。Java推荐在javadoc中提供信息,告知用户为什么这个方法被弃用了,以及替代方法是什么。

    3. @SuppressWarnings – 这个注解仅仅是告知编译器,忽略它们产生了特殊警告,比如:在java泛型中使用原始类型。它的保持性策略(retention policy)是SOURCE,在编译器中将被丢弃。

    我们来看一个例子,展示了如何使用内置注解,以及上述示例中提及的自定义注解。

     1 package com.journaldev.annotations;
     2  
     3 import java.io.FileNotFoundException;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6  
     7 public class AnnotationExample {
     8  
     9     public static void main(String[] args) {
    10     }
    11  
    12     @Override
    13     @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)
    14     public String toString() {
    15         return "Overriden toString method";
    16     }
    17  
    18     @Deprecated
    19     @MethodInfo(comments = "deprecated method", date = "Nov 17 2012")
    20     public static void oldMethod() {
    21         System.out.println("old method, don't use it.");
    22     }
    23  
    24     @SuppressWarnings({ "unchecked", "deprecation" })
    25     @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)
    26     public static void genericsTest() throws FileNotFoundException {
    27         List l = new ArrayList();
    28         l.add("abc");
    29         oldMethod();
    30     }
    31  
    32 }

    我相信这个例子是很明了的,展示了不同场景下注解的使用方式。

    Java注解解析

    我们将使用Java反射机制从一个类中解析注解,请记住,注解保持性策略应该是RUNTIME,否则它的信息在运行期无效,我们也不能从中获取任何数据。

     
     1 package com.journaldev.annotations;
     2  
     3 import java.lang.annotation.Annotation;
     4 import java.lang.reflect.Method;
     5  
     6 public class AnnotationParsing {
     7  
     8     public static void main(String[] args) {
     9         try {
    10             for (Method method : AnnotationParsing.class
    11                     .getClassLoader()
    12                     .loadClass(("com.journaldev.annotations.AnnotationExample"))
    13                     .getMethods()) {
    14                 // checks if MethodInfo annotation is present for the method
    15                 if (method
    16                         .isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
    17                     try {
    18                         // iterates all the annotations available in the method
    19                         for (Annotation anno : method.getDeclaredAnnotations()) {
    20                             System.out.println("Annotation in Method '"
    21                                     + method + "' : " + anno);
    22                         }
    23                         MethodInfo methodAnno = method
    24                                 .getAnnotation(MethodInfo.class);
    25                         if (methodAnno.revision() == 1) {
    26                             System.out.println("Method with revision no 1 = "
    27                                     + method);
    28                         }
    29  
    30                     } catch (Throwable ex) {
    31                         ex.printStackTrace();
    32                     }
    33                 }
    34             }
    35         } catch (SecurityException | ClassNotFoundException e) {
    36             e.printStackTrace();
    37         }
    38     }
    39  
    40 }

    以上程序的输出是:

    Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
    Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
    Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
    Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

    注解API非常强大,被广泛应用于各种Java框架,如Spring,Hibernate,JUnit。可以查看《Java中的反射》获得更多信息。

    这就是java注解教程的全部内容了,我希望你能从中学到一些东西。

  • 相关阅读:
    HDU 5528 Count a * b 欧拉函数
    HDU 5534 Partial Tree 完全背包
    HDU 5536 Chip Factory Trie
    HDU 5510 Bazinga KMP
    HDU 4821 String 字符串哈希
    HDU 4814 Golden Radio Base 模拟
    LA 6538 Dinner Coming Soon DP
    HDU 4781 Assignment For Princess 构造
    LA 7056 Colorful Toy Polya定理
    LA 6540 Fibonacci Tree
  • 原文地址:https://www.cnblogs.com/cxxjohnson/p/8319920.html
Copyright © 2011-2022 走看看