`

Java中Annotation学习笔记

    博客分类:
  • Java
阅读更多
Annotation就是注释,在J2SE 5.0中,注释是以‘@注释名’在代码中存在的,例如:J2SE 5.0内置的注释:@Override、@Deprecated;有的注释还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked");对于这种只有一个参数,且参数名为value的注释,我们在使用时可以简写为:@SuppressWarnings("unchecked")。

Annotation有三类,一类是标准的Annotation,而且号称“即拆即用”(out of thebox),也就是直接可以用,是包含在java.lang中的系统自带的。第二类是自己定义的annotation,第三类则是metaannotation(元注释)。使用annotation时,前面要加“@”
(一)第一类annotation。有三个,分别是override,deprecated和SupressWarning。前两个功能和javadoc中是一样的,为了注明某个方法或者字段是否为重载的或者废弃的。而第三个则是用来控制编译选项的,叫做“抑制警告”。
1. @Override注释能实现编译时检查,你可以为你的方法添加该注释,以声明该方法是用于覆盖父类中的方法。如果该方法不是覆盖父类的方法,将会在编译时报错。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;代码如下:
package com.gelc.annotation.demo.basic;
public class OverrideDemo {
    // @Override
    public String tostring() {
        return super.toString();
    }
}

在编译时,则会提示以下错误信息:
OverrideTest.java:5: 方法未覆盖其父类的方法
        @Override

         ^
1 错误

    就像示例演示的那样,该注释一大好处就是可以在编译时帮我们捕获部分编译错误,但又有多少编程人员愿意为每个覆盖父类的方法添加该注释呢?这个只有靠编程人员自己进行取舍了。
2. @Deprecated的作用是对不应该在使用的方法添加注释,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能,准确的说,它还不如javadoc @deprecated,因为它不支持参数,使用@Deprecated的示例代码示例如下:
package com.gelc.annotation.demo.basic;
public class DeprecatedDemo {
    public static void main(String[] args) {
        // DeprecatedClass.DeprecatedMethod();
    }
}
class DeprecatedClass {
    @Deprecated
    public static void DeprecatedMethod() {
        // TODO
    }
}
    编译时,会得到以下提示:
注意:DeprecatedDemo.java 使用或覆盖了已过时的 API。
注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。
    如果在编译时添加-Xlint:deprecation参数,我们能更清楚的看到该警告的详细信息,如下:
DeprecatedDemo.java:6: 警告:[deprecation] SomeClass 中的 DeprecatedMethod() 已
过时
                SomeClass.DeprecatedMethod();
                         ^
1 警告

    通过上面的示例,你已经掌握到了如何使用@Deprecated,但你理解到@Deprecated与@deprecated的区别了吗?你可以简单的理解为:@Deprecated是为了编译时检查,而@deprecated是为了生成文档的需要,各尽其责。
3. SupressWarning需要一个参数,语法如下:
   @SupressWarning(value={"uncheck"})
这个注释只作用于他所注释的方法或者类,而不是javac那样对整个源文件起作用。其参数如下:

参数             语义
deprecation    使用了过时的类或方法时的警告
unchecked      执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型
fallthrough    当 Switch 程序块直接通往下一种情况而没有 Break 时的警告
path           在类路径、源文件路径等中有不存在的路径时的警告
serial          当在可序列化的类上缺少 serialVersionUID 定义时的警告
finally         任何 finally 子句不能正常完成时的警告
all             关于以上所有情况的警告

例如:
          
@SuppressWarnings("unchecked")
	@Override
	public String execute() throws Exception
	{
		Map request = (Map) ActionContext.getContext().get("request");
		request.put("list", service.findAll());
		return SUCCESS;
	}

(二)自己定义annotation。annotation的定义采用interface的形式(隐含的表示annotation其实是一个特殊的接口)
   public @interface EXAMPLE{
    String value()
   }
  以接口的形式定义annotation的名字,以方法的形式定义annotation的member(member好像是类里面的公有字段,或者称为annotation的属性,属性可以是一个也可以多个),用的时候如下
   @EXAMPLE("happy time")
   public void testmethod(){}
  把happy time作为“value”这个member的值。
  还有比较复杂的用法,比如在EXAMPLE的里面加上Enum的声明,然后让你的member值只能是Enum中限定的值,等等。
例如:
public class AnnotationTest {
    @NewAnnotation("Just a Test.")
    public static void main(String[] args) {
        sayHello();
        sayHelloWithDefaultFontColor();
        sayHelloWithRedFontColor();
    }
    @NewAnnotation("Hello NUMEN.")
    public static void sayHello() {
        //do something
    }
    @Greeting(name="NUMEN", content="Hello")
    public static void sayHelloWithDefaultFontColor() {
        // do something
    }
    @Greeting(name="NUMEN", content="Hello", fontColor=Greeting.FontColor.RED )
    public static void sayHelloWithRedFontColor() {
        // do something
    }
}

(三)metaannotation。元注释又叫“注释的注释”,顾名思义,是用来定义annotation的一组annotation,用在自定义annotation时。就像所谓的metadata(元信息),即“信息的信息”。元注释有四种,
一是target,即这个注释可以被用在哪些地方。
二是documented,即这个注释能否出现在生成的javadoc中。
三是Retention,决定编译器和JVM如何处理这个注释。
四是Inherited,即这个注释能否被继承下去,就是说,当被注释的类继承以后,他的子类还会不会有这个注释。
   @Inherited
   @Documentd
   public @interface EXAMPLE{}
这段代码的意思是:这个EXAMPLE注释要出现在生成的javadoc中,而且当EXAMPLE修饰一个类时,它的子类同样会得到EXAMPLE,也就是“继承”的意思了。
限定注释使用范围

   当我们的自定义注释不断的增多也比较复杂时,就会导致有些开发人员使用错误,主要表现在不该使用该注释的地方使用。为此,Java提供了一个ElementType枚举类型来控制每个注释的使用范围,比如说某些注释只能用于普通方法,而不能用于构造函数等。下面是Java定义的ElementType枚举:

package java.lang.annotation;

public enum ElementType {
  TYPE,         // Class, interface, or enum (but not annotation)
  FIELD,        // Field (including enumerated values)
  METHOD,       // Method (does not include constructors)
  PARAMETER,        // Method parameter
  CONSTRUCTOR,      // Constructor
  LOCAL_VARIABLE,   // Local variable or catch clause
  ANNOTATION_TYPE,  // Annotation Types (meta-annotations)
  PACKAGE       // Java package
}

    下面我们来修改Greeting注释,为之添加限定范围的语句,这里我们称它为目标(Target)使用方法也很简单,如下:
package com.gelc.annotation.demo.customize;

@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
    public enum FontColor {
        RED, GREEN, BLUE
    };
    String name();
    String content();
    FontColor fontColor() default FontColor.BLUE;
}

正如上面代码所展示的,我们只允许Greeting注释标注在普通方法和构造函数上,使用在包申明、类名等时,会提示错误信息。
注释保持性策略
    在Java编译器编译时,它会识别在源代码里添加的注释是否还会保留,这就是RetentionPolicy。下面是Java定义的RetentionPolicy枚举:

编译器的处理有三种策略:

Ø         将注释保留在编译后的类文件中,并在第一次加载类时读取它

Ø         将注释保留在编译后的类文件中,但是在运行时忽略它

Ø         按照规定使用注释,但是并不将它保留到编译后的类文件中
package java.lang.annotation;

public enum RetentionPolicy {
  SOURCE,       // Annotation is discarded by the compiler
  CLASS,        // Annotation is stored in the class file, but ignored by the VM
  RUNTIME       // Annotation is stored in the class file and read by the VM
}
RetentionPolicy的使用方法与ElementType类似,简单代码示例如下:
package com.gelc.annotation.demo.customize;

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

@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
    public enum FontColor {
        RED, GREEN, BLUE
    };
    String name();
    String content();
    FontColor fontColor() default FontColor.BLUE;
}

文档化功能

    Java提供的Documented元注释跟Javadoc的作用是差不多的,其实它存在的好处是开发人员可以定制Javadoc不支持的文档属性,并在开发中应用。它的使用跟前两个也是一样的,简单代码示例如下:
package com.gelc.annotation.demo.customize;

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

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
    public enum FontColor {
        RED, GREEN, BLUE
   };
 
    String name();
    String content();
    FontColor fontColor() default FontColor.BLUE;
}
值得大家注意的是,如果你要使用@Documented元注释,你就得为该注释设置RetentionPolicy.RUNTIME保持性策略。为什么这样做,应该比较容易理解,这里就不提了。

标注继承

继承应该是Java提供的最复杂的一个元注释了,它的作用是控制注释是否会影响到子类,简单代码示例如下:
package com.gelc.annotation.demo.customize;

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

@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
    public enum FontColor {
      RED, GREEN, BLUE
    };
    String name();
    String content();
    FontColor fontColor() default FontColor.BLUE;
}

读取注释信息

    当我们想读取某个注释信息时,我们是在运行时通过反射来实现的,如果你对元注释还有点印象,那你应该记得我们需要将保持性策略设置为RUNTIME,也就是说只有注释标记了@Retention(RetentionPolicy.RUNTIME)的,我们才能通过反射来获得相关信息,下面的例子我们将沿用前面几篇文章中出现的代码,并实现读取AnnotationTest类所有方法标记的注释并打印到控制台。好了,我们来看看是如何实现的吧:
package com.gelc.annotation.demo.reflect;

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

public class AnnotationIntro {
    public static void main(String[] args) throws Exception {
        Method[] methods = Class.forName(
                "com.gelc.annotation.demo.customize.AnnotationTest")
                .getDeclaredMethods();
        Annotation[] annotations;

        for (Method method : methods) {
            annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(method.getName() + " : "
                        + annotation.annotationType().getName());
            }
        }
    }
}
分享到:
评论

相关推荐

    无线电能传输中电动汽车充电的Matlab与Maxwell仿真:线圈结构与补偿拓扑优化

    内容概要:本文详细介绍了无线电能传输技术在电动汽车充电中的应用,特别是在Matlab和Maxwell中的仿真过程。首先讨论了SS补偿拓扑的Matlab仿真,展示了如何设置线圈参数、进行谐振匹配以及通过相量分析判断软开关状态。接着探讨了Maxwell中DD线圈的3D电磁场仿真,强调了自定义网格划分和涡流场计算的重要性。随后,文章深入研究了多线圈阵列仿真,揭示了不同线圈布局对耦合系数的影响,并提出了LCC补偿拓扑的应用。此外,文中还分享了许多实用技巧,如避免常见错误、优化仿真参数以及处理实际测试中的问题。 适合人群:从事无线电能传输研究的技术人员、研究生及以上学历的研究人员。 使用场景及目标:适用于需要深入了解无线电能传输技术及其仿真的研究人员和技术开发者,旨在帮助他们掌握Matlab和Maxwell的具体应用,提高仿真精度和效率。 其他说明:文章不仅提供了详细的代码示例和仿真步骤,还分享了作者的实际经验和教训,使读者能够更好地理解和应对仿真过程中遇到的问题。

    用户增删改查功能的前端页面,添加了vue渲染代码

    用户增删改查功能的前端页面,添加了vue渲染代码。

    计算机课程设计相关资源

    计算机课程设计相关资源

    基于51单片机protues仿真的猜数字游戏(仿真图、源代码、AD原理图、流程图)

    基于51单片机protues仿真的猜数字游戏(仿真图、源代码、AD原理图、流程图) 猜数字游戏 1、通过随机数实现该游戏; 2、按下K1键启动游戏并随机生成一个0~9的数字 3、通过矩阵按键输入你的数字,输入数字小于随机生成的数字则显示小于该数,大于的时候显示大于该数,直到相等为止。 4、仿真图、源代码、AD原理图、流程图;

    基于MATLAB的FOC滑膜观测器与锁相环(MATLAB 2021b)实现及硬件移植注意事项

    内容概要:本文详细介绍了利用MATLAB 2021b搭建的FOC滑膜观测器(SMO)与锁相环(PLL)的仿真模型及其在M4硬件平台上的实现方法。文中首先展示了SMO的核心代码,解释了如何通过滑模面计算和符号函数处理来估算反电动势,并讨论了PLL用于速度提取的具体实现。接着探讨了仿真环境中直接0速闭环启动的效果以及实际硬件实现时所需的开环启动策略。此外,文章还分享了多个调试过程中遇到的问题及解决方案,如相位跳变、高频振荡、电流环参数调整等。 适合人群:从事电机控制研究的技术人员,尤其是对无感FOC感兴趣的工程师。 使用场景及目标:适用于希望深入了解FOC滑膜观测器和锁相环的工作原理并尝试将其应用于实际项目的开发者。目标是掌握SMO+PLL组合的设计思路和技术细节,同时了解硬件移植时需要注意的实际问题。 其他说明:文中提供了大量实用的代码片段和调试经验,对于想要快速入门或优化现有系统的读者非常有帮助。特别强调了仿真与现实之间的差异,提醒读者注意参数选择和滤波器设计等方面的不同之处。

    汽车美容员工手册.doc

    汽车美容员工手册.doc

    基于PSO算法的配电网分布式光伏选址定容优化及其Matlab实现

    内容概要:本文详细介绍了利用粒子群优化(PSO)算法解决配电网中分布式光伏系统的选址与定容问题的方法。首先阐述了问题背景,即在复杂的配电网环境中选择合适的光伏安装位置和确定合理的装机容量,以降低网损、减小电压偏差并提高光伏消纳效率。接着展示了具体的PSO算法实现流程,包括粒子初始化、适应度函数构建、粒子位置更新规则以及越界处理机制等关键技术细节。文中还讨论了目标函数的设计思路,将多个相互制约的目标如网损、电压偏差和光伏消纳通过加权方式整合为单一评价标准。此外,作者分享了一些实践经验,例如采用前推回代法进行快速潮流计算,针对特定应用场景调整权重系数,以及引入随机波动模型模拟光伏出力特性。最终实验结果显示,经过优化后的方案能够显著提升系统的整体性能。 适用人群:从事电力系统规划与设计的专业人士,尤其是那些需要处理分布式能源集成问题的研究人员和技术人员。 使用场景及目标:适用于希望深入了解如何运用智能优化算法解决实际工程难题的人士;旨在帮助读者掌握PSO算法的具体应用方法,从而更好地应对配电网中分布式光伏系统的选址定容挑战。 其他说明:文中提供了完整的Matlab源代码片段,便于读者理解和复现研究结果;同时也提到了一些潜在改进方向,鼓励进一步探索和创新。

    晋升考核制度.pptx

    晋升考核制度.pptx

    计网-主机发送IP数据报的过程思维导图

    计网-主机发送IP数据报的过程思维导图

    三菱FX3U PLC与三台E740变频器基于Modbus RTU通讯的工业自动化控制系统实现

    内容概要:本文详细介绍了三菱FX3U PLC与三台三菱E740变频器通过Modbus RTU协议进行通讯的具体实现方法。主要内容涵盖硬件配置(如PLC、变频器、触摸屏)、通讯参数设置(如波特率、数据位、校验方式)、PLC程序编写(包括初始化、启停控制、频率设定等)、触摸屏编程(如画面设计、变量关联)等方面。文中还分享了一些实际应用中的注意事项和避坑指南,确保通讯系统的稳定性和可靠性。 适用人群:从事工业自动化领域的工程师和技术人员,尤其是熟悉三菱产品和Modbus RTU协议的专业人士。 使用场景及目标:适用于需要实现PLC与多台变频器通讯的工业自动化项目,旨在提高系统的集成度和可控性,减少人工干预,提升生产效率。 其他说明:文中提供的实例和代码片段有助于读者快速理解和掌握相关技术要点,同时强调了实际操作中的常见问题及其解决方案。

    自动驾驶路径跟踪:基于二/三自由度动力学模型的MPC算法及Carsim-Simulink联合仿真

    内容概要:本文深入探讨了利用二/三自由度动力学模型和MPC(模型预测控制)实现自动驾驶车辆的任意路径跟踪技术。首先介绍了二自由度动力学模型的基本概念及其状态方程,随后详细解释了MPC的工作原理,包括目标函数的设计和优化求解过程。接着讨论了Carsim和Simulink联合仿真的具体实施步骤和技术要点,如采样同步、约束条件处理等。文中还分享了许多实用的工程经验和调试技巧,例如预瞄距离的设置、权重矩阵的选择以及如何应对高速工况下的挑战。最终通过仿真结果展示,证明了该方法的有效性和优越性。 适合人群:从事自动驾驶研究与开发的专业人士,尤其是对路径跟踪算法感兴趣的工程师和技术爱好者。 使用场景及目标:适用于需要精确路径跟踪的自动驾驶应用场景,旨在提高车辆行驶的安全性和效率。通过掌握本文介绍的方法和技术,可以帮助开发者更好地理解和实现基于MPC的路径跟踪系统。 其他说明:文章不仅提供了理论知识,还包括了大量的实战经验和代码片段,有助于读者快速上手并应用于实际项目中。同时强调了在不同速度范围选择合适自由度模型的重要性,为后续的研究和发展指明了方向。

    基于博途1200PLC的智能灌溉系统设计与实现 - 自动化农业应用

    内容概要:本文详细介绍了基于西门子S7-1200 PLC的智能灌溉系统的设计与实现。系统主要包括PLC控制器、触摸屏、传感器和执行机构。文中详细讲解了如何使用博途V16软件编写PLC程序,包括梯形图编程和SCL语言的应用,以及如何设计触摸屏监控画面。此外,还涉及了IO表和电气原理图的准备,确保系统的正确安装和维护。文章特别强调了自动灌溉的核心逻辑,如状态机结构和异常处理机制,以及触摸屏设计的小技巧,如动态图标和趋势图的使用。最后,提供了调试过程中的一些注意事项和优化建议。 适合人群:从事农业自动化领域的工程师和技术人员,尤其是熟悉PLC编程和触摸屏设计的专业人士。 使用场景及目标:适用于需要提高灌溉效率和精度的现代农业生产环境。目标是通过智能化控制减少水资源浪费,提升作物产量。同时,也为系统开发者提供了详细的实施指南和调试技巧。 其他说明:文章附带了完整的PLC程序、HMI界面和电气图纸,方便读者进行实际操作和验证。

    MINIQMT学习课程Day5

    国金qmt模拟客户端。 模拟账号密码,私聊。

    员工离职面谈记录表.doc

    员工离职面谈记录表.doc

    新员工关怀方案.doc

    新员工关怀方案

    轴承表面缺陷检测数据集解析:基于Python的图像处理与模型训练

    内容概要:本文详细介绍了轴承表面缺陷检测数据集的结构及其应用方法。数据集包含5824张高清轴承图像及其对应的XML标注文件,涵盖擦伤、凹槽、划痕三种类型的缺陷。作者通过Python代码展示了如何检查数据完整性、解析XML标注文件、进行数据可视化以及数据增强操作。此外,还讨论了使用YOLOv5和EfficientDet等模型进行缺陷检测的具体步骤和技术要点,强调了高分辨率图像处理和模型优化的方法。 适合人群:从事工业质检、机器视觉、深度学习等相关领域的研究人员和工程师。 使用场景及目标:适用于需要处理高分辨率工业图像并进行缺陷检测的研究和工程项目。主要目标是提高缺陷检测的准确性,特别是在复杂的工业环境中。 其他说明:文中提供了大量实用的Python代码片段,涵盖了从数据预处理到模型训练的各个环节。特别提到了针对金属表面反光、多缺陷共存等问题的技术解决方案。

    招聘甘特图.xlsx

    招聘甘特图.xlsx

    招聘仪表盘构建及为数据解读P11.pptx

    招聘仪表盘构建及为数据解读P11.pptx

    基于MATLAB的光纤通信物理层传输算法仿真与调试技巧

    内容概要:本文详细介绍了利用MATLAB进行光纤通信物理层传输算法仿真的方法和技术要点。主要内容涵盖色散补偿、非线性放大器建模、信号重构、时钟恢复、QPSK调制、误码率分析等方面。文中提供了多个具体的MATLAB代码示例,如色散补偿、非线性放大器特性拟合、QPSK调制与解调、眼图生成等,并分享了许多调试经验和常见问题解决方案。此外,作者还强调了仿真过程中需要注意的关键细节,如参数设置、变量监控、噪声注入方式等。 适合人群:从事光纤通信研究的技术人员、研究生以及对通信系统仿真感兴趣的开发者。 使用场景及目标:适用于希望深入了解光纤通信物理层传输机制及其仿真实现的研究人员和工程师。目标是帮助读者掌握MATLAB在通信仿真中的应用,提高仿真效率并减少调试时间。 其他说明:文章不仅提供详细的代码示例,还分享了大量实战经验,有助于读者快速上手并解决实际问题。

    线性代数_李宏毅_视频笔记_学习辅助_1742822508.zip

    线性代数

Global site tag (gtag.js) - Google Analytics