java annotation

Java Annotations允许我们将元数据信息添加到源代码中,尽管它们不是程序本身的一部分。 注释从JDK 5添加到java中。注释对它们注释的代码的操作没有直接影响(即它不影响程序的执行)。
 
一.java 内建annotation
1.@Override
在覆盖子类中的方法时,我们应该使用此批注来标记该方法。 这使得代码可读并避免维护问题,例如:在更改父类的方法签名时,必须更改子类中的签名(使用此批注的位置),否则编译器将抛出编译错误。 如果未使用此注释,则很难跟踪。
示例
@Override
public String toString() {
    return super.toString();
}
2.@Deprecated
@Deprecated注释表示已弃用标记的元素(类,方法或字段),不应再使用它。 只要程序使用已经使用@Deprecated注释标记的方法,类或字段,编译器就会生成警告。 不推荐使用元素时,也应使用Javadoc @deprecated标记对其进行记录,如以下示例所示。 记下@Deprecated和@deprecated的大小写差异。 @deprecated用于文档目的。
示例
/**
* @deprecated
* 我们废弃了oldMethod.建议调用newMethod
*/
@Deprecated
public void oldMethod(){
 
}
public void newMethod(){
 
}
  • 3.@SuppressWarnings
此批注指示编译器忽略特定警告。 例如,在下面的代码中,我调用了一个不推荐使用的方法(假设方法deprecatedMethod()用@Deprecated注释标记)所以编译器应该生成警告,但是我使用@@ SuppressWarnings注释来抑制弃用 警告。
示例
//@SuppressWarnings("deprecation")  
public void app() {
    oldMethod();
}
 
@SuppressWarnings("deprecation")
public void app() {
    oldMethod();
}
 
 
二.用户自定义注解
  • 注释是使用@interface创建的,后跟注释名称,如下例所示。
  • 注释也可以包含元素。 它们看起来像方法。 例如,在下面的代码中,我们有四个元素。 我们不应该为这些元素提供实现。
  • 所有注释都扩展了java.lang.annotation.Annotation接口。 注释不能包含任何extends子句。
package com.jason.test.annotation;
 
import java.lang.annotation.*;
 
@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAnnotation {
    int studentAge() default 18;
 
    String studentName();
 
    String stuAddress();
 
    String stuStream() default "CSE";
}
 
 
注意:使用注释时,可以跳过在创建注释时设置了默认值的所有元素。 例如,如果我将上述注释应用于类,那么我会这样做:
 
@MyCustomAnnotation(studentName = "Milk", stuAddress = "SH")
public void newMethod() {
 
}
 
如您所见,我们没有给studentAge和stuStream元素赋值,因为设置这些元素的值是可选的(默认值已经在Annotation定义中设置,但是如果您希望在使用注释时可以指定新值 就像我们对其他元素一样)。 但是,我们必须在使用注释时提供其他元素的值(没有设置默认值的元素)。
 
注意:我们也可以在注释中包含数组元素。 这就是我们如何使用它们:
注释定义:
 
@interface MyCustomAnnotation {
    int      count();
    String[] books();
}
 
使用:
@MyCustomAnnotation(
    count=3,
    books={"C++", "Java"}
)
public class MyClass {
 
}
 
再次回到主题:在自定义注释示例中,我们使用了这四个注释:@Documented,@ Target,@ Inherited和@Retention。 让我们详细讨论它们。
 
@Documented
@Documented注释表明使用此注释的元素应由JavaDoc记录。 例如:
java.lang.annotation.Documented
@Documented
public @interface MyCustomAnnotation {
  //Annotation body
}
@MyCustomAnnotation
public class MyClass {
     //Class body
}
 
在为MyClass类生成javadoc时,注释@MyCustomAnnotation将包含在其中。
 
@Target
它指定了我们可以使用注释的位置。 例如:在下面的代码中,我们将目标类型定义为METHOD,这意味着下面的注释只能用于方法。
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
 
@Target({ElementType.METHOD})
public @interface MyCustomAnnotation {
 
}
public class MyClass {
   @MyCustomAnnotation
   public void myMethod()
   {
       //Doing something
   }
}
 
注意:1)如果您没有定义任何Target类型,则意味着可以将注释应用于任何元素。
2)除了ElementType.METHOD之外,注释可以具有以下可能的Target值:
ElementType.METHOD
ElementType.PACKAGE
ElementType.PARAMETER
ElementType.TYPE
ElementType.ANNOTATION_TYPE
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.FIELD
 
@Inherited
@Inherited注释表明类中使用的自定义注释应该由其所有子类继承。 例如:
java.lang.annotation.Inherited
 
@Inherited
public @interface MyCustomAnnotation {
 
}
 
@MyCustomAnnotation
public class MyParentClass {
  ...
}
 
public class MyChildClass extends MyParentClass {
   ...
}
这里的MyParentClass类使用注释@MyCustomAnnotation,该注释用@inherited注释标记。 这意味着子类MyChildClass继承了@MyCustomAnnotation。
 
@Retention
它指示要保留带注释类型的注释的时间长度。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
 
@Retention(RetentionPolicy.RUNTIME)
@interface MyCustomAnnotation {
    
}
 
 
 
 三.java annotation reflect (scala 编写)
package com.program

import com.jason.test.annotation.{Fooy, MyCustomAnnotation}

object AnnoTest {
  def main(args: Array[String]): Unit = {
    //========获取类的注解========
    val clazz = classOf[Fooy]
    for (anno <- clazz.getAnnotations) {
      if (anno.isInstanceOf[MyCustomAnnotation]) {
        val a = (anno.asInstanceOf[MyCustomAnnotation])
        println(a.studentAge())
      }
    }
    //========获取类的注解========

    //==========获取方法的注解==========
    val method = clazz.getMethod("newMethod")
    for (anno <- method.getAnnotations) {
      if (anno.isInstanceOf[MyCustomAnnotation]) {
        val a = (anno.asInstanceOf[MyCustomAnnotation])
        println(a.studentName())
      }
    }
    //==========获取方法的注解==========

    //==========获取属性的注解==========
    val field = clazz.getField("name")
    for (anno <- field.getAnnotations) {
      if (anno.isInstanceOf[MyCustomAnnotation]) {
        val a = (anno.asInstanceOf[MyCustomAnnotation])
        println(a.stuAddress())
      }
    }
    //==========获取属性的注解==========
  }
}

 

 
 
posted @ 2018-12-25 18:35  生心无住  阅读(271)  评论(0编辑  收藏  举报