首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java 注解(Annotation)

Java 注解(Annotation)

作者头像
全栈程序员站长
发布于 2022-09-08 03:27:49
发布于 2022-09-08 03:27:49
45500
代码可运行
举报
运行总次数:0
代码可运行

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

文章目录

Annotation工作方式

从Java5.0版发布以来,5.0平台提供了一个正式的annoatation功能:允许开发者定义、使用自己的annotation类型。此功能由一个定义annotation声明的语法,读取annotation的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。

annotation并不直接影响代码语义,但是它能够工作的方式被看作类似程序的工具或者类库,它会反过来对正在运行的程序语义有所影响。 annotation可以从源文件、class文件或者以在运行时反射的多种方式被读取。

JDK5 内建Annotation

Java 注解(Annotation):

限定Override父类方法@Override

java.langOverride是个Marker annotation 用于标示的Annotation,Annotation名称本身即表示了要给工具程序的信息 a) Override 注解表示子类要重写(override) 父类的对应方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

public class OverrideTest { 
   

	@Override
	public String toString() { 
   
		return "This is OverrideTest";
	}
	
	public static void main(String[] args) { 
   
		OverrideTest test = new OverrideTest();
		
		System.out.println(test);
	}
}

结果是: This is OverrideTest

标示方法为Deprecated @Deprectated

对编译程序说明某个方法已经不建议使用,即该方法是过时的。 java.lang.Deprecated也是个Marker annotation Deprecated这个名称在告知编译程序,被@Deprecated标示的方法是一个不建议被使用的方法 b) Deprecated 注解表示方法是不建议被使用的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

import java.sql.Date;

public class DeprecatedTest { 
   

	@Deprecated
	public void doSomething() { 
   
		System.out.println("do something");
	}

	public static void main(String[] args) { 
   
		
		DeprecatedTest test = new DeprecatedTest();
		
		test.doSomething();
		
		
		
		/*Date date = new Date(0); System.out.println(date.toLocaleString());*/
	}
}

结果是: do something

抑制编译程序警告@SuppressWarnings

对编译程序说明某个方法中若有警告讯息,则加以抑制 c) SuppressWarnings 注解表示抑制警告。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

public class SuppressWarningTest { 
   

	@SuppressWarnings({ 
    "unchecked", "rawtypes" })
	public static void main(String[] args) { 
   
		Map map = new TreeMap();
		
		map.put("hello", new Date());
		
		System.out.println(map.get("hello"));
	}
}

结果是: Sun Jan 13 19:59:06 CST 2019

自定义Annotation类型

定义Marker Annotation,也就是Annotation名称本身即提供信息对于程序分析工具来说,主要是检查是否有Marker Annotation的出现,并作出对应的动作。

自定义注解:当注解中的属性名为 value 时,在对其赋值时可以不指定属性的名称 而直接写上属性值即可;除了 value 以外的其他值都需要使用 name=value 这种赋值 方式,即明确指定给谁赋值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

public @interface AnnotationTest { 
   
	
	String value1();

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

public @interface AnnotationTest1 { 
   

	String value();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

@AnnotationTest(value1 = "hello")
public class AnnotationUsage { 
   
	
	@AnnotationTest1("world")
	public void method() { 
   
		System.out.println("usage of annotation");
	}
	
	public static void main(String[] args) { 
   
		AnnotationUsage usage = new AnnotationUsage();
		
		usage.method();
	}

}

结果是: usage of annotation

Single-value annotation

value成员设定默认值,用”default”关键词 数组方式的使用 枚举在Annotation中的应用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

public @interface AnnotationTest1 { 
   

	String[] value1() default "hello";
	EnumTest value2();
}

enum EnumTest{ 
   
	Hello, World, Welcome
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package sixtyNineth;

@AnnotationTest1(value2 = EnumTest.Welcome, value1 = "world")
public class AnnotationUsage { 
   
	
	@AnnotationTest1(value1 = { 
   "hello","haha"}, value2 = EnumTest.Hello)
	public void method() { 
   
		System.out.println("usage of annotation");
	}
	
	public static void main(String[] args) { 
   
		AnnotationUsage usage = new AnnotationUsage();
		
		usage.method();
	}

}

使用@interface自定义Annotation型态时,实际上是自动继承了java.lang.annotation.Annnotation接口由编译程序自动为您完成其它产生的细节,在定义Annotation型态时,不能继承其他的Annotation型态或者接口。 java.lang.annotation Interface Annotation

The common interface extended by all annotation types. Note that an interface that manually extends this one does not define an annotation type. Also note that this interface does not itself define an annotation type.

当 我 们 使 用 @interface 关 键 字 定 义 一 个 注 解 时 , 该 注 解 隐 含 地 继 承 了java.lang.annotation.Annotation 接口;如果我们定义了一个接口,并且让该接口继承自 Annotation,那么我们所定义的接口依然还是接口而不是注解; Annotation 本身是接口而不是注解。 (可以与 Enum 类比。)

定义Annotation型态时也可以使用包来管理类别方式类同于类的导入功能。

告知编译程序如何处理@Retention

java.lang.annotation.Retention型态可以在您定义Annotation型态时,指示编译程序该如何对待您的自定义的Annotation型态。 ==预设上编译程序会将Annotation信息留在.class档案中,==但是不被虚拟机读取,而仅用于编译程序或工具程序运行时提供信息。 在使用Retention型态时,需要提供java.lang.annotation.RetentionPolicy的枚举型态Package java.lang.annotation;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public enum RetentionPolicy
{ 
   
    SOURCE,//编译程序处理完Annotation信息后就完成任务
    CLASS//编译程序将Annotation储存于class档中,缺省,不由VM读入
    RUNTIME //编译程序将Annotation储存于class档中,可由VM读入,通过反射的方式读取到
}

RetentionPolicy为SOURCE的例子是@SuppressWarnings 仅在编译时期告知编译程序来抑制警告,所以不必将这个信息储存于.class档案 RetentionPolicy为RUNTIME的时机,可以像是您使用Java设计一个程序代码分析工具,您让VM能读出Annotation信息,以便在分析程序时使用。 搭配反射(Reflectiong)机制,就可以达到这个目的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation { 
   

    String hello() default "Matthew";

    String world();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

@MyAnnotation(hello = "beijing", world = "shanghai")
public class MyTest { 
   

    @MyAnnotation(hello = "tianjing", world = "shangdi")
    @Deprecated
    @SuppressWarnings("unchecked")
    public void output(){ 
   
        System.out.println("output something");
    }

    public static void main(String[] args) { 
   
        MyTest myTest = new MyTest();

        myTest.output();
    }

}

java.lang.reflect.AnnotatedElement接口 public Annotation getAnnotation(Class annotationType); public Annotation[] getAnnotations(); public Annotation[] getDeclaredAnnotations(); public boolean isAnnotationPresent(Class annotationType); Class、Constructor、Field、Method、Package等类别,都实现了AnnotationElement接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String hello() default "Matthew";

    String world();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

@MyAnnotation(hello = "beijing", world = "shanghai")
public class MyTest { 
   

    @MyAnnotation(hello = "tianjing", world = "shangdi")
    @Deprecated
    @SuppressWarnings("unchecked")
    public void output(){ 
   
        System.out.println("output something");
    }

   /* public static void main(String[] args) { MyTest myTest = new MyTest(); myTest.output(); }*/

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

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

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[]{});

        if(method.isAnnotationPresent(MyAnnotation.class)){
            method.invoke(myTest, new Object[]{});

            MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);

            String hello = myAnnotation.hello();
            String world = myAnnotation.world();

            System.out.println(hello + "," + world);
        }

        Annotation[] annotations = method.getAnnotations();

        for(Annotation annotation : annotations){
            System.out.println(annotation.annotationType().getName());
        }

    }
}

结果是: output something tianjing,shangdi Seventieth.First.MyAnnotation java.lang.Deprecated

当我们在@Retention(RetentionPolicy.RUNTIME)不用RUNTIME而用CLASS和SOURCE时,运行结果为空,因为注解存在了class文件当中,但是,VM不会反射读取出来,method.isAnnotationPresent(MyAnnotation.class)为false所以没有输出。 @Retention(RetentionPolicy.SOURCE) 因为SuppressWarnings的RetentionPolicy为SOURCE

限定annotation使用对象@Target

使用java.lang.annotation.Target可以定义其使用的时机,在定义时要指定java.lang.annotation.ElementType的枚举值之一 package java.lang.annotation; public enum ElementType{ TYPE,//适用class,interface,enum FIELD,//适用field METHOD,//适用method PARAMETER,//适用method上的parameter CONSTRUCTOR,//适用costructor LOCAL_VARIABLE,//适用局部变量 ABBOTATION_TYPE,//适用annotation型态 PACKAGE//适用package }

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
public @interface MyTarget { 
   

    String value();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

public class MyTargetTest { 
   

    @MyTarget("hello")
    public void doSomething(){ 
   

        System.out.println("hello world");

    }

}

如果把 @MyTarget(“hello”)放在类上面就会报错’@MyTarget’ not applicable to type,我们把 @Target(ElementType.METHOD)改为@Target(ElementType.TYPE)就不会报错了

要求为API文件@Documented

想要在使用者制作JavaDoc文件的同时,也一并将Annotation的讯息加入至API文件中使用java.lang.annotation.Documented

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

public @interface DocumentedAnnotation {
    String hello();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

public class DocumentedTest {
    @DocumentedAnnotation(hello = "welcome")
    public void method(){
        System.out.println("hello world");
    }
}

生成java帮助文档在Tool》Generate JavaDoc 然后在弹出的界面点击Output directory后的按钮选择文档生成路径 接下来在底部的Locale输入框配置语言和编码集,如下图所示,语言用zh_CN,代表中文

点击ok生成帮助文档

这就是我生成的java帮助文档,点击DocumentTest拉到最下面有方法详细资料

我们将DoucumentedAnnotation.java更改一下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.First;

import java.lang.annotation.Documented;

@Documented
public @interface DocumentedAnnotation { 
   
    String hello();
}

再次生成帮助文档,我们发现发发详细资料变成如下图所示的样子

子类是否继承父类@Inherited

预设上夫类别中断Annotation并不会被继承至子类别中,可以在定义Annotation型态时加上java.lang.annotation.Inherited型态的Annotation

通过JUnit深入理解反射与注解的使用方式与场景

现在项目中导入jar包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.Secound;

import junit.framework.TestCase;

public class Test extends TestCase { 
   


    public void testAdd(){ 
   
        System.out.println("hello world");
    }

    public void testSubtract(){ 
   
        System.out.println("welcome");
    }

}

结果是: hello world welcome

方法必须以test开头,JUnit我们学过反射后应该大致了解其思路,首先获得这个类的Class对象,然后获得其所有的方法,存入Method[]然后遍历每一个方法,getName获得方法名,如果是以test开头就通过method.invoke执行这个方法

JUnit(3.8、 4.x): Keep the bar green to keep the code clean.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package Seventieth.Secound;

import org.junit.Test;

public class Test2 { 
   
    @Test
    public void hello(){ 
   
        System.out.println("hello world");
    }
}

JUnit4 的执行的一般流程: a) 首先获得待测试类所对应的 Class 对象。 b) 然后通过该 Class 对象获得当前类中所有 public 方法所对应的 Method 数组。 c) 遍历该 Method 数组,取得每一个 Method 对象 d) 调用每个 Method 对象的 isAnnotationPresent(Test.class)方法,判断该方法是否被 Test 注解所修饰。 e) 如果该方法返回 true,那么调用 method.invoke()方法去执行该方法,否则不执行。

单元测试不是为了证明你是对的,而是证明你没有错误。 Writing Secure Code(编写安全的代码): Input is evil。

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java注释@interface的用法
java用 @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类
全栈程序员站长
2022/09/07
5310
Java注释@interface的用法
面试系列之-JAVA注解剖析(JAVA基础)
(01) 1个Annotation 和 1个RetentionPolicy关联。可以理解为:每1个Annotation对象,都会有唯一的RetentionPolicy属性。
用户4283147
2023/08/21
1730
面试系列之-JAVA注解剖析(JAVA基础)
Java 注解(Annotation
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
joshua317
2021/12/20
9850
Java 注解(Annotation
19 浅析 Java 注解(Annotation)
Java 5之后可以在源代码中嵌入一些补充信息,这种补充信息称为注解(Annotation),例如在方法覆盖中使用过的@Override注解,注解都是@符号开头的。
acc8226
2022/05/17
2310
19 浅析 Java 注解(Annotation)
注解(Annotation) 转
  注解(Annotation)很重要,未来的开发模式都是基于注解的,JPA是基于注解的,Spring2.5以上都是基于注解的,Hibernate3.x以后也是基于注解的,现在的Struts2有一部分也是基于注解的了,注解是一种趋势,现在已经有不少的人开始用注解了,注解是JDK1.5之后才有的新特性
wuweixiang
2018/11/12
6900
Java注解Annotation详解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
java干货
2021/02/19
6120
java基础第十八篇之单元测试、注解和动态代理
1:单元测试 1)JUnit是一个Java语言的单元测试框架,这里的单元指的就是方法 2)单元测试用来替换以前的main方法
海仔
2019/08/05
4510
Java 注解
    从JDK1.5开始,引入了源代码中的注解这一机制。注解使得 Java 源代码中不但可以包含功能性的实现代码,还可以包含元数据。
JMCui
2018/09/27
1.7K0
Java Annotation 注解
首先什么是注解? 最常见的是,在我们使用Eclipse等工具编写java代码的时候,有时候会出现一些比如@Deprecated,@Override,@SuppressWarnings等东东。这个就是常
I Teach You 我教你
2018/01/02
5880
Java Annotation 注解
详解Java中的注解
在Java中,注解(Annotation)引入始于Java5,用来描述Java代码的元信息,通常情况下注解不会直接影响代码的执行,尽管有些注解可以用来做到影响代码执行。
技术小黑屋
2018/09/05
6260
spring自定义注解实现(spring里面的注解)
1.SOURCE:在源文件中生效,仅存在java文件中,class文件将会去除注解。
全栈程序员站长
2022/07/30
8220
spring自定义注解实现(spring里面的注解)
【云+社区年度征文】深入理解Java注解
基本概念:注解,顾名思义,就是对某一事物进行添加注释说明,会存放一些信息,这些信息可能对以后某个时段来说是很有用处的。Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 语言中的类、方法、变量、参数和包等都可以被标注(添加某些信息)。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以通过反射的方式获取到标注内容 。 当然它也支持自定义 的Java 标注。
Simon郎
2020/12/22
6460
java自定义注解和使用[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/129174.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/29
2530
你说啥什么?注解你还不会?
元注解就是注解自定义注解的注解。可能有点饶,一会看例子就明白了,直白点就是给你自定义的注解上一定要加的注解。
手撕代码八百里
2020/10/26
4820
深入浅出 Java 注解!
所谓注解,其实就像一种拥有特定作用的注释,自 JDK1.5 及之后版本所引入的特性,它是放在 Java 源码的类、方法、字段、参数前的一种用作标注的“元数据”,与类、接口、枚举处于同一个层次中。
村雨遥
2021/07/07
3470
Java注解的学习
Java 定义了一套注解,共有 7 个,3 个在 java.lang 中,剩下 4 个在 java.lang.annotation 中。
乐心湖
2020/07/31
6080
Java注解的学习
详解Java注解(Annotation)
从JDK5开始,Java增加了对元数据的支持,也就是注解Annotation。注解就是代码里的特殊标记,这些标记可以在编译、类加载和运行时被读取,并进行相应的处理。通过使用注解,开发人员可以在不改变原有逻辑的基础上,在源文件中嵌入一些补充信息。 Annotation是一个接口,程序可以通过反射机制来获取指定程序元素的Annotation对象,然后通过Annotation对象来取得注解中的元数据。值得注意的是,Annotaion并不影响程序的执行,无论添加、删除注解,代码都照常运行。
张申傲
2020/09/03
3250
java 注解简述
注解(annotation)相当于一个运行于内存当中的自定义类型的数据存储区域,理解以后才发现它的好用,就是数据存储区,相当于一个运行在内存当中的XML,所有的注解数据在JDK加载完类以后,就可以被使用。
潇洒
2023/10/20
2100
Java5 注解(Annotation)
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。注解是结合反射来运行的,注解相当于一个标识,不做具体的操作,具体操作是由反射来完成的。
HLee
2021/05/26
7460
Java5 注解(Annotation)
Java 使用注解
在 Java 开发领域,注解(Annotation)是一项极为重要且强大的特性。它就像是给代码添加的特殊标记或标签,能够在不改变原有代码逻辑的基础上,为程序提供额外的元数据信息,从而实现诸如代码自动生成、运行时动态处理、配置简化等丰富功能,极大地提升了开发效率和代码的灵活性与可维护性。
编程小白狼
2024/12/31
1150
相关推荐
Java注释@interface的用法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验