Java注释@interface的用法

Java注释@interface的用法java用@interfaceAnnotation{} 定义一个注解@Annotation,一个注解是一个类@Override,@Deprecated,@SuppressWarni

大家好,又见面了,我是你们的朋友全栈君。

java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类

@Override,@Deprecated,@SuppressWarnings为常见的3个注解。
注解相当于一种标记,在程序中加上了注解就等于为程序加上了某种标记,以后,
JAVAC编译器,开发工具和其他程序可以用反射来了解你的类以及各种元素上有无任何标记,看你有什么标记,就去干相应的事

 

注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法的名字出错时,编译器就会报错,如图:

<span role="heading" aria-level="2">Java注释@interface的用法
       注解@Deprecated,用来表示某个类的属性或方法已经过时,不想别人再用时,在属性和方法
上用@Deprecated修饰,如图:

<span role="heading" aria-level="2">Java注释@interface的用法

  注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候,
 如图:

  <span role="heading" aria-level="2">Java注释@interface的用法

注解@Retention可以用来修饰注解,是注解的注解,称为元注解

Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,
这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值:CLASS  RUNTIME   SOURCE
用@Retention(RetentionPolicy.CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;
用@Retention(RetentionPolicy.SOURCE )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中;
用@Retention(RetentionPolicy.RUNTIME )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,
所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.

package com.self;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
  
@Retention(RetentionPolicy.RUNTIME)  
public @interface MyTarget  
{ } 

定义个一注解@MyTarget,用RetentionPolicy.RUNTIME修饰;

package com.self;  
import java.lang.reflect.Method;  
public class MyTargetTest  
{  
 @MyTarget  
 public void doSomething()  
 {  
  System.out.println("hello world");  
 }  
   
 public static void main(String[] args) throws Exception  
 {  
  Method method = MyTargetTest.class.getMethod("doSomething",null);  
  if(method.isAnnotationPresent(MyTarget.class))//如果doSomething方法上存在注解@MyTarget,则为true  
  {  
   System.out.println(method.getAnnotation(MyTarget.class));  
  }  
  }  
}  

上面程序打印:@com.self.MyTarget(),如果RetentionPolicy值不为RUNTIME,则不打印

@Retention(RetentionPolicy.SOURCE )  
public @interface Override  
  
@Retention(RetentionPolicy.SOURCE )  
public @interface SuppressWarnings  
  
@Retention(RetentionPolicy.RUNTIME )  
public @interface Deprecated  

由上可以看出,只有注解@Deprecated在运行时可以被JVM读取到  

注解中可以定义属性,看例子:

@Retention(RetentionPolicy.RUNTIME)  
public @interface MyAnnotation  
{  
 String hello() default "gege";  
  String world();  
  int[] array() default { 2, 4, 5, 6 };  
  EnumTest.TrafficLamp lamp() ;  
  TestAnnotation lannotation() default @TestAnnotation(value = "ddd");  
  Class style() default String.class;  
}  

上面程序中,定义一个注解@MyAnnotation,定义了6个属性,他们的名字为:  

hello,world,array,lamp,lannotation,style.  

  • 属性hello类型为String,默认值为gege  
  • 属性world类型为String,没有默认值  
  • 属性array类型为数组,默认值为2,4,5,6  
  • 属性lamp类型为一个枚举,没有默认值  
  • 属性lannotation类型为注解,默认值为@TestAnnotation,注解里的属性是注解  
  • 属性style类型为Class,默认值为String类型的Class类型  

看下面例子:定义了一个MyTest类,用注解@MyAnnotation修饰,注解@MyAnnotation定义的属性都赋了值

@MyAnnotation(hello = "beijing", world="shanghai",array={},lamp=TrafficLamp.RED,style=int.class)  
public class MyTest  
{  
 @MyAnnotation(lannotation=@TestAnnotation(value="baby"), world = "shanghai",array={1,2,3},lamp=TrafficLamp.YELLOW)  
 @Deprecated  
 @SuppressWarnings("")  
 public void output()  
 {  
  System.out.println("output something!");  
 }  
}  

接着通过反射读取注解的信息:  

public class MyReflection  
{  
 public static void main(String[] args) throws Exception  
 {  
  MyTest myTest = new MyTest();  
    Class<MyTest> c = MyTest.class;  
    Method method = c.getMethod("output", new Class[] {});  
       //如果MyTest类名上有注解@MyAnnotation修饰,则为true  
  if(MyTest.class.isAnnotationPresent(MyAnnotation.class))  
  {  
   System.out.println("have annotation");  
  }  
   if (method.isAnnotationPresent(MyAnnotation.class))  
   {  
   method.invoke(myTest, null); //调用output方法  
   //获取方法上注解@MyAnnotation的信息  
     MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);  
    String hello = myAnnotation.hello();  
   String world = myAnnotation.world();  
   System.out.println(hello + ", " + world);//打印属性hello和world的值  
   System.out.println(myAnnotation.array().length);//打印属性array数组的长度  
   System.out.println(myAnnotation.lannotation().value()); //打印属性lannotation的值  
   System.out.println(myAnnotation.style());  
   }  
    //得到output方法上的所有注解,当然是被RetentionPolicy.RUNTIME修饰的  
     Annotation[] annotations = method.getAnnotations();  
      for (Annotation annotation : annotations)  
  {  
   System.out.println(annotation.annotationType().getName());  
  }  
   }  
}  

上面程序打印:  

have annotation  
output something!  
gege, shanghai  
3  
baby  
class java.lang.String  
com.heima.annotation.MyAnnotation  
java.lang.Deprecated 

如果注解中有一个属性名字叫value,则在应用时可以省略属性名字不写。  

可见,@Retention(RetentionPolicy.RUNTIME )注解中,RetentionPolicy.RUNTIME是注解属性值,属性名字是value,  

属性的返回类型是RetentionPolicy,如下:

public @interface MyTarget  
{  
    String value();  
}  

可以这样用:  

@MyTarget("aaa")  
 public void doSomething()  
 {  
  System.out.println("hello world");  
 }  

注解@Target也是用来修饰注解的元注解,它有一个属性ElementType也是枚举类型,  

值为:ANNOTATION_TYPE CONSTRUCTOR  FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE  

@Target(ElementType.METHOD) 修饰的注解表示该注解只能用来修饰在方法上

@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface MyTarget  
{  
 String value() default "hahaha";  
}  

如把@MyTarget修饰在类上,则程序报错,如:

@MyTarget  
public class MyTargetTest 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/154415.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 程序人生-感受湖光景色随笔

    开头聊几句1、首先在说明下,我不是大佬,我是渣飞,这个“渣”是技术方面,不要想多,虽然我现在渣,但是我希望不断努力朝大佬的方向靠近2、今天是周四,我司的周四特定上线日,每月总有那么几天,在公司待待很晚。公司楼下有个湖,最近几次上线,有空都会去下面走走3、从公司上线完后,趁着验证功能的时间,写下此篇4、今天闲踱湖边,想写点东西,记录下,写完估计验证也完了,就回家了5、本文非技术文章,是一篇记录自己生活的随笔,我定义自己的程序人生。喜欢看技术文的伙伴可以忽略开头之前文章说过,这是我的一个小

    2022年3月1日
    31
  • H.264/MPEG-4 AVC学习

    H.264/MPEG-4 AVC学习转自:https://www.freehacker.cn/media/codec-h264/简述H.264,又称为MPEG-4第10部分,高级视频编码(英语:MPEG-4Part10,AdvancedVideoCoding,缩写为MPEG-4AVC)是一种面向块的基于运动补偿的视频编码标准。对于视频序列样本来说,使用H.264编码器能够比使用有运动补偿的MPEG-…

    2022年9月19日
    0
  • poe交换机和普通交换机区别_交换机可以接交换机吗

    poe交换机和普通交换机区别_交换机可以接交换机吗一个完整的POE系统包括供电端设备(PSE,PowerSourcingEquipment)和受电端设备(PD,PowerDevice)两部分,POE交换机为PSE设备的一种。PSE设备是为以太网客户端设备供电的设备,同时也是整个POE以太网供电过程的管理者。而PD设备是接受供电的PSE负载,即POE系统的客户端。POE交换机和普通交换机哪里不同?POE交换机和普通交换机有什么不同,P…

    2022年10月5日
    0
  • oracle数据库心得体会_oracle基础知识入门

    oracle数据库心得体会_oracle基础知识入门Oracle的体系太庞大了,对于初学者来说,难免会有些无从下手的感觉,什么都想学,结果什么都学不好,所以把学习经验共享一下,希望让刚刚入门的人对oracle有一个总体的认识,少走一些弯路。  一、定位  oracle分两大块,一块是开发,一块是管理。开发主要是写写存储过程、触发器什么的,还有就是用Oracle的Develop工具做form。有点类似于程序员,需要有较强的逻辑思维和创造能力,

    2022年8月30日
    1
  • keil如何生成bin文件_keil4生成bin文件

    keil如何生成bin文件_keil4生成bin文件如何利用KEIL生成bin文件并且用于固件更新?生成bin文件KEIL在编译完成后在Object目录下生成axf文件,我们可以使用fromelf工具将axf文件转化为bin文件。在User选项卡中可以看到如果勾选了Run#1选项,那么在编译完成之后(AfterBuild/Rebuild),就会执行该选项下的命令。接下来详细的探讨利用fromelf.exe转换工具是如何生成bin文件的。首先我们了解fromelf.exe转换工具的语法其格式如下:fromelf[…

    2022年10月20日
    0
  • 最大矩形 —— 单调栈「建议收藏」

    最大矩形 —— 单调栈「建议收藏」https://cn.vjudge.net/contest/245662#problemAhistogramisapolygoncomposedofasequenceofrectanglesalignedatacommonbaseline.Therectangleshaveequalwidthsbutmayhavedifferentheigh…

    2022年9月22日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号