Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java进阶(一)Annotation(注解)

Java进阶(一)Annotation(注解)

原创
作者头像
Jason Guo
修改于 2018-04-27 13:33:55
修改于 2018-04-27 13:33:55
1.4K1
举报
文章被收录于专栏:大数据架构大数据架构

原创文章,转载请务必将下面这段话置于文章开头处(保留超链接)。 本文转发自技术世界原文链接 http://www.jasongj.com/2016/01/17/Java1_注解Annotation

概念

Annotation是Java5开始引入的特性。它提供了一种安全的类似于注释和Java doc的机制。实事上,Annotation已经被广泛用于各种Java框架,如Spring,Jersey,JUnit,TestNG。注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效。这些元数据与程序业务逻辑无关,并且是供指定的工具或框架使用的。

Meta Annotation

元注解的作用就是负责注解其他注解。Java5定义了4个标准的Meta Annotation类型,它们被用来提供对其它 Annotation类型作说明。

@Target

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了@Target可更加明晰其修饰的目标。

@Target作用:用于描述注解的使用范围,即被描述的注解可以用在什么地方

@Target取值(ElementType)

  • CONSTRUCTOR:用于描述构造器
  • FIELD:用于描述域
  • LOCAL_VARIABLE:用于描述局部变量
  • METHOD:用于描述方法
  • PACKAGE:用于描述包
  • PARAMETER:用于描述参数
  • TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention

@Retention定义了该Annotation的生命周期:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。@Retention有唯一的value作为成员。

@Retention作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)

@Retention取值来自java.lang.annotation.RetentionPolicy的枚举类型值

  • SOURCE:在源文件中有效(即源文件保留)
  • CLASS:在class文件中有效(即class保留)
  • RUNTIME:在运行时有效(即运行时保留)

@Documented

@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。@Documented是一个标记注解,没有成员。

@Inherited

@Inherited 是一个标记注解。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个Annotation将被用于该class的子类。

自定义Annotation

在实际项目中,经常会碰到下面这种场景,一个接口的实现类或者抽象类的子类很多,经常需要根据不同情况(比如根据配置文件)实例化并使用不同的子类。典型的例子是结合工厂使用职责链模式。

此时,可以为每个实现类加上特定的Annotation,并在Annotation中给该类取一个标识符,应用程序可通过该标识符来判断应该实例化哪个子类。

下面这个例子,定义了一个名为Component的Annotation,它包含一个名为identifier的成员变量。

代码语言:txt
AI代码解释
复制
package com.jasongj.annotation;

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Component {
    String identifier () default "";
}

对于上文所说的实现类加上@Component

代码语言:txt
AI代码解释
复制
package com.jasongj;

import com.jasongj.annotation.Component;

@Component(identifier="upper")
public class UpperCaseComponent {

    public String doWork(String input) {
        if(input != null) {
            return input.toUpperCase();
        } else {
            return null;
        }
    }
}

应用程序中可以通过反射获取UpperCaseComponent对应的identifie

代码语言:txt
AI代码解释
复制
package com.jasongj;

import com.jasongj.annotation.Component;

public class Client {
    public static void main(String[] args) {
        try {
            Class componentClass = Class.forName("com.jasongj.UpperCaseComponent");
            if(componentClass.isAnnotationPresent(Component.class)) {
                Component component = (Component)componentClass.getAnnotation(Component.class);
                String identifier = component.identifier();
                System.out.println(String.format("Identifier for "
                    + "com.jasongj.UpperCaseComponent is ' %s '", identifier));
            } else {
                System.out.println("com.jasongj.UpperCaseComponent is not annotated by"
                        + " com.jasongj.annotation.Component");
            }
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }
}

结果如下

代码语言:txt
AI代码解释
复制
Identifier for com.jasongj.UpperCaseComponent is ' upper '

如果把@Component@Retention设置为 RetentionPolicy.SOURCE或者RetentionPolicy.CLASS,则会得到如下结果,验证了上文中对@Retention的描述

代码语言:txt
AI代码解释
复制
com.jasongj.UpperCaseComponent is not annotated by com.jasongj.annotation.Component

Java内置Annotation

Annotation的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准Annotation,定义在java.lang中:

  1. @Override 是一个标记型Annotation,说明了被标注的方法覆盖了父类的方法,起到了断言的作用。如果给一个非覆盖父类方法的方法添加该Annotation,编译器将报编译错误。它有两个典型的使用场景,一是在试图覆盖父类方法却写错了方法名时报错,二是删除已被子类覆盖(且用Annotation修饰)的父类方法时报错。
  2. @Deprecated 标记型Annotation,说明被修改的元素已被废弃并不推荐使用,编译器会在该元素上加一条横线以作提示。该修饰具有一定的“传递性”:如果我们通过继承的方式使用了这个弃用的元素,即使继承后的元素(类,成员或者方法)并未被标记为@Deprecated,编译器仍然会给出提示。
  3. @SuppressWarnnings 用于通知Java编译器关闭对特定类、方法、成员变量、变量初始化的警告。此种警告一般代表了可能的程序错误,例如当我们使用一个generic collection类而未提供它的类型时,编译器将提示“unchecked warning”的警告。通常当这种情况发生时,我们需要查找引起警告的代码,如果它真的表示错误,我们就需要纠正它。然而,有时我们无法避免这种警告,例如,我们使用必须和非generic的旧代码交互的generic collection类时,我们无法避免这个unchecked warning,此时可以在调用的方法前增加@SuppressWarnnings通知编译器关闭对此方法的警告。

@SuppressWarnnings不是标记型Annotation,它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。常见的警告名为下。

  • unchecked 执行了未检查的转换时的警告。例如当使用集合时没有用泛型来指定集合的类型
  • finally finally子句不能正常完成时的警告
  • fallthrough 当switch程序块直接通往下一种情况而没有break时的警告
  • deprecation 使用了弃用的类或者方法时的警告
  • seriel 在可序列化的类上缺少serialVersionUID时的警告
  • path 在类路径、源文件路径等中有不存在的路径时的警告
  • all 对以上所有情况的警告

Annotation与Interface的异同

  • Annotation类型使用关键字@interface而非interface。注意开头的@符号
  • Annotataion的方法定义是受限制的。其方法必须声明为无参数、无异常抛出的。这些方法同时也定义了Annotation的成员——方法名即为成员名,而方法返回类型即为成员类型。方法返回类型必须为Java基础类型、Class类型、枚举类型、Annotation类型或者相应的一维数组。方法后面可以使用default关键字和一个默认数值来声明成员的默认值,null不能作为成员默认值。成员一般不能是泛型,只有当其类型是Class时可以使用泛型,因为此方法能够用类型转换将各种类型转换为Class
  • Annotation和interface都可以定义常量、静态成员类型,也都可以被实现或者继承

Java进阶系列

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
1 条评论
热度
最新
很实用的文章,之前也看过一篇类似的
很实用的文章,之前也看过一篇类似的
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
Java Review(三十五、注解)
注解能被用来为程序元素( 类、 方法、 成员变量等) 设置元数据。 值得指出的是, 注解不影响程序代码的执行, 无论增加、 删除注解, 代码都始终如一地执行。 如果希望让程序中的注解在运行时起一定的作用, 只有通过某种配套的工具对注解中的信息进行访问和处理, 访问和处理注解的工具统称 APT( Annotation Processing Tool )。
三分恶
2020/07/16
3540
你分析过注解 Annotation 的实现原理吗?
对于很多初次接触的开发者来说应该都有这个疑问?Annontation是Java5开始引入的新特征,中文名称叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且供指定的工具或框架使用。
JavaFish
2019/10/17
7K0
面试官:说说你对【注解】的理解
现在已经处于注解盛行时代,注解@Override ,这个注解是再熟悉不过了,还有@Controller、@RequestMapping、@Service.....
田维常
2020/12/14
4170
Java注解总结
  所谓注解,其实是代码里的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行 相应的处理。通过使用注解,程序开发人员可以在不改变原有逻辑的情况下,在源文件中嵌入一些补充的信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
程序员云帆哥
2022/05/12
3950
java基础-注解Annotation原理和用法
转载自 http://www.wolfbe.com/detail/201608/265.html
allsmallpig
2021/02/25
4380
Java基础(十三):注解(Annotation)
冬天vs不冷
2025/01/21
2290
java系列之注解
我们在实际项目开发中使用注解的目的:为了追求低耦合,降低后期的维护成本。平时自己在实际项目也会经常用到注解,所以想着自己总结一下注解的知识点,毕竟"好记性不如烂笔头",忘记的时候可以自己打开文章梳理一下,下面开始进入正文。
沁溪源
2020/09/03
5080
Java 使用注解
在 Java 开发领域,注解(Annotation)是一项极为重要且强大的特性。它就像是给代码添加的特殊标记或标签,能够在不改变原有代码逻辑的基础上,为程序提供额外的元数据信息,从而实现诸如代码自动生成、运行时动态处理、配置简化等丰富功能,极大地提升了开发效率和代码的灵活性与可维护性。
编程小白狼
2024/12/31
920
Java – 注解 (Annotation)
> 使用 Annotation 时要在其前面增加 @符号,并把该 Annotation 当成一个修饰符使用,用于修饰它支持的程序元素
全栈程序员站长
2022/07/20
2550
你说啥什么?注解你还不会?
元注解就是注解自定义注解的注解。可能有点饶,一会看例子就明白了,直白点就是给你自定义的注解上一定要加的注解。
手撕代码八百里
2020/10/26
4640
Java 注解机制
注解是 JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。它主要的作用有以下四方面: 【1】生成文档:通过代码里标识的元数据生成 javadoc文档。 【2】编译检查:通过代码里标识的元数据让编译器在编译期间进行检查验证。 【3】编译时动态处理:编译时通过代码里标识的元数据动态处理,例如动态生成代码。 【4】运行时动态处理:运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
Java架构师必看
2021/05/14
6290
深入理解 Java 注解
从本质上来说,注解是一种标签,其实质上可以视为一种特殊的注释,如果没有解析它的代码,它并不比普通注释强。
静默虚空
2019/12/20
1.1K0
深入理解 Java 注解
19 浅析 Java 注解(Annotation)
Java 5之后可以在源代码中嵌入一些补充信息,这种补充信息称为注解(Annotation),例如在方法覆盖中使用过的@Override注解,注解都是@符号开头的。
acc8226
2022/05/17
2240
19 浅析 Java 注解(Annotation)
Java中的注解,自定义注解
注解(Annotation)是从JDK5.0开始引入,以“@注解名”在代码中存在。
鱼找水需要时间
2023/04/23
5720
Java进阶-注解
注解(Annotation)是Java 5 版本之后可以在源代码中嵌入的一种补充信息,是 Java 平台中非常重要的一部分。这次的内容如下
reload
2024/03/08
1840
Java进阶-注解
Java中的注解
Annotation(注解)是Java JDK5及其以后版本中引入的一个特性。注解是Java的一个新的类型(与接口类似),它与类、接口、枚举是在同一个层次,它们都称为Java的一个类型(TYPE)。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。它的作用非常多,进行编译检查、生成说明文档、代码分析等。
卡尔曼和玻尔兹曼谁曼
2019/01/25
7050
Java 注解(Annotation)
从Java5.0版发布以来,5.0平台提供了一个正式的annoatation功能:允许开发者定义、使用自己的annotation类型。此功能由一个定义annotation声明的语法,读取annotation的API,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。
全栈程序员站长
2022/09/08
4440
Java 注解 Annotation
概述 了解 Java 注解前必须先了解元注解。 元注解:描述注解的注解。 如果明白元数据概念就比较好理解元注解 元数据:描述数据的数据。 还是比较抽象哈,下面举个例子说明下。 比如一个txt文件的元数据有 : 文件大小、创建时间、最后修改时间等数据。 JDK提供了4种元注解 @Retention 声明注解的生命周期 @Target 修饰注解可以使用到那些目标对象上 @Document 提取javadoc 文档 @Inherited 继承性,使用它,子类也集成该类的注解 1.@Retentio
java404
2018/05/18
7920
Java-Java5.0注解解读
Java5.0注解可以看做Javadoc和Xdoclet标签的延伸和发展,在Java5.0中可以自定义这些标签,并通过Java语言的反射机制获取类中标注的注解,完成特定的功能。
小小工匠
2021/08/16
2560
Java 注解 —— 注解的理解、注解的使用与自定义注解
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ajianyingxiaoqinghan/article/details/81436118
剑影啸清寒
2019/05/26
3.2K0
相关推荐
Java Review(三十五、注解)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档