首页 > 编程语言 > Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解

Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解

时间:2023-02-22 19:24:12浏览次数:48  
标签:Java warnings suppress value 注解 设计模式 annotation 属性

Java ”框架 = 注解 + 反射 + 设计模式“ 之 注解详解

在这里插入图片描述

每博一文案

刹那间我真想令时光停住,好让我回顾自己,回顾失去的年华,缅怀哪个穿一身短小的连衣裙
和瘦窄的短衫的小女孩。让我追悔少年时代,我心灵的愚钝无知,它轻易地错过了我一生中本来
可以获得欢乐和幸福。
                             —————— 《平凡的世界》
                             
真的,如果痛苦不能改变生存,那还不如平静地将自己毁灭,毁灭,一切都毁灭了,
只有生命还在苟延残喘,这样的生命还有有什么存在的价值。
                            —————— 《平凡的世界》
                     

@

目录

1. 注解的概念

注解,一种元数据形式提供了一个不属于程序本身的程序的数据。注解对他们注解的代码的操作没有直接的影响。

注解有很多用途,其中:

  • 编译器的信息 - 编译器可以使用注解来检测错误或抑制警告。
  • 编译和部署时处理 - 软件工具可以处理注解信息以生成代码,XML 文件等。
  • 运行时处理 - 一些注解可以在运行时检查

JDK5.0 开始,Java增加了对元数据(MetaData) 的支持,也就是 Annotation 注解。

  • 注解: 其实就是代码里的 特殊标记 ,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过使用 注解,

程序员可以在不改变原有的逻辑的情况下,在源文件种嵌入一些补充的信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或进行部署。

  • 注解: 可以像修饰符一样被使用,可以用于 修饰:包,类,构造器,方法,成员变量,参数,局部变量的声明 。这些信息被保存在 注解 Annotaion 的“ name = value” 键值对中。

  • JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE/Android中注解占据了更重要的角色,例如

    用来配置应用程序的任何切面,代替JavaEE旧版中所遗留的繁冗 代码和XML配置等。

  • 未来的开发模式都是基于注解的,JPA 是基于注解的,Spring2.5 以上都是基于注解的,Hibernate3.x 以后也是基于注解的,

现在Struts2 有一部分也是基于注解的了。注解是一种趋势,一定程度上可以说:框架 = 注解 + 反射 + 设计模式

2. 注解的作用

JVM 的角度看,注解本身对代码逻辑没有任何影响,如何使用注解完全由工具决定。

Java的注解可以分为三类:

  • 第一类:是由编译器使用的注解:换句话说就是给编译器看的,不是给 JVM 看的。例如:
    • @Override : 让编译器检查该方法是否正确的实现了 重写操作。
    • @Deprecated : 表示所修饰的元素(类,方法等)已过时了,不建议使用它了。
    • @SuppressWarnings: 告诉编译器忽略此处代码产生的警告。
  • 第二类: 是由工具处理 .class 文件使用的注解,比如有些工具会在加载 class 的时候,对 class 做动态修改,实现一些特殊的功能。这类注解会被编译进入到 .class 文件,但加载结束后并不会存在于内存中。这类注解只被一些底层使用,一般我们不必自己处理。
  • 第三类: 是在程序运行期间能够读取的注解,它们在加载后一直存在于 JVM 中,这也是最常用的注解。例如:一个配置了@PostConstruct 的方法会在调用构造方法后自动被调用,(这是Java代码读取该注解实现的功能,JVM 并不会识别该注解)。

3. 文档注释中的注解

在这里插入图片描述

在这里插入图片描述

  • @author 标明开发该类模块的作者,多个作者之间使用,分割。
  • @version 标明该类的模块的版本。
  • @see 参考转向,也就是相关类的主题。
  • @since 从哪个版本开始增加的。
  • @param 对方法中某参数的说明,如果没有参数就不能写。
  • @return 对方法返回值的说明,如果方法的返回值类型是 void 就不能写
  • @exception 对方法可能抛出的异常进行说明,如果方法没有用 throws 显抛出的异常就不能写 其中:
    • @param @ return 和 @ exeption 这三个标记都是只用于方法的。
    • @param 的格式要求:@param 形参名 形参类型 形参说明
    • @return 的格式要求:@return 返回值类型 返回值说明
    • @exception 的格式要求:@exception 异常类型 异常说明
    • @ param 和 @exception 可以并列多个。

4. 自定义注解

Annotaion注解 其实也是一种引用数据类型,编译之后也是生成 xxx.class 字节码文件的。

  • 定义新的 Annotation 注解 类型使用 @interface 关键字

  • 自定义注解自动实现了 java.lang.annotation.Annotation接口

在这里插入图片描述

在这里插入图片描述

自定义注解的格式如下:

public @interface MyAnnotation {
    
}

// 
[修饰列表] @interface 注解名/(注解类名) {
    
}

使用 IDEA 创建一个 注解类型: 鼠标右键 ——> new 一个选择 :

在这里插入图片描述

如下查看该 我们该自定义的注解 MyAnnotation 的 UML 图:可以清楚的看到该 注解类型是自动继承了该 java.lang.annotation.Annotation 接口的

在这里插入图片描述

但是事实上却是自动实现了 java.lang.annotation.Annotation 接口。

在这里插入图片描述

Java 8之前,注解只能是在声明的地方所使用,Java8 开始,注解可以应用 在任何地方 。这里的任何地方包括:包,类,构造器,方法,成员变量,参数,局部变量的声明 。这些信息被保存在 注解 Annotaion 的“ name = value” 键值对中。

举例如下: 并没有出现任何的报错的情况。

在这里插入图片描述

4.1 注解中的属性

在注解中可以定义属性。

Java中的注解中的属性:看着像方法,但实际在注解当中是属性 name

格式如下:

String value();
// 数据类型 属性名();  // 看似是方法,其实在注解中是属性

注解中的属性可以是任何类型:byte, short, int, long, float, double, boolean, char, String, long, Class, 枚举类型。再或者是自定义类型。

举例:

public @interface MyAnnotation {
    
    String value();

}

注意: 如果该注解中定义了属性,则声明使用该注解时 必须 为其注解中的属性值赋上值,不然,是会报错的。

如下,我们为该 @MyAnnotation 注解定义了属性,使用时却没有赋值,报如下编译错误。

在这里插入图片描述

为注解中的属性赋值的格式如下:

@MyAnnotaion(value="Tom") // 注意:在该注解中定义的是什么类型的值,就赋值对应的值,不然会报错的
// @注解名(注解中的属性名=对应赋值的属性值)

举例:

在这里插入图片描述

如果该注解中只有一个属性值,并且该注解的属性名为 value ,则在赋值时,可以省略其 为value的属性名,直接写值

注意一定要满足两个条件:1. 该注解中只有一个属性值,2.该属性名为 value

举例:

在这里插入图片描述


为注解中的多个属性赋值格式如下: 多个属性值,使用逗号分隔开来,就可以了。

 @MyAnnotation(value = "Tom",value2 = "123")
// @注解名(注解中的属性名=值,注解中的属性名=值) :多个属性值使用逗号分隔开。

注意: 当注解中存在多个属性值时,其中所有该注解中的属性值都必须赋值,不然编译报错,如下:

在这里插入图片描述

必须将注解中的所有属性值都赋值上值才行:如下:如果注解中存在两个或两个以上的属性,就算其中存在一个属性名为 value ,其赋值时,该value 属性名是不可以省略的。必须写明所有的属性名的进行赋值。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在这里插入图片描述

注解中的属性可以设置默认值,使用关键字``格式如下:

String value() default "Tom";
// 数据类型 属性名() default  默认值;  注意需要和定义的类型保证一致。

举例:

public @interface MyAnnotation {
    String value() default "Tom";

}

注解中属性设置了,默认值的是可以选择不进行赋值操作,使用定义的默认值。

举例如下:

在这里插入图片描述

4.2 注解中属性为:数组的赋值

注解中的属性值是可以定义为数组属性的格式如下:

String[] arr(); // 定义数组为属性值
数据类型[] 属性名(); 

举例:

public @interface MyAnnotation {

    String value();

    String[] arr();

}

注解中以数组为属性的赋值格式如下:

@MyAnnotation(value = "Tom",arr = {"hello","world"})
@注解名(属性名=值,属性名={值,值})

举例:

在这里插入图片描述

当数组属性所赋值的参数只有一个时,可以省略{} 花括号。如下

在这里插入图片描述

5. JDK 内置的三个基本注解

下面我们来认识一下,JDK 中三个常见的基本注解。

5.1 @Override: 限定重写父类方法, 该注解只能用于方法

在这里插入图片描述

@Override : 的作用就是在编译期间:让编译器检查该方法是否正确的实现了 重写 操作。其中的重写的方法名是否存在错误,方法的返回值类型是否是父类中/接口中的一致。不一致编译报错,提示我们改正。

@OVerride 注解的源码,可以看到该注解是没有定义属性的。

package java.lang;

import java.lang.annotation.*;

/**
 * Indicates that a method declaration is intended to override a
 * method declaration in a supertype. If a method is annotated with
 * this annotation type compilers are required to generate an error
 * message unless at least one of the following conditions hold:
 *
 * <ul><li>
 * The method does override or implement a method declared in a
 * supertype.
 * </li><li>
 * The method has a signature that is override-equivalent to that of
 * any public method declared in {@linkplain Object}.
 * </li></ul>
 *
 * @author  Peter von der Ah&eacute;
 * @author  Joshua Bloch
 * @jls 9.6.1.4 @Override
 * @since 1.5
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

注意 : 该注解只能使用在方法上(因为该注解的源码中被@Target(ElementType.METHOD)元注解修饰了),在其他位置上是会编译报错的。如下:

在这里插入图片描述


@OVerride 注解的使用: 较少了我们编程程序时,上的简单符号上以及一些基本的语法错误。

在这里插入图片描述

5.2 @Deprecated: 用于表示所修饰的元素(类, 方法等)已过时。

在这里插入图片描述

@Deprecated : 该注解表示:表示所修饰的元素(类,方法等)已过时了,不建议使用它了。建议替换成其他的方法。

@Depecated 源码: 可以看到该注解是没有定义属性的。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * A program element annotated &#64;Deprecated is one that programmers
 * are discouraged from using, typically because it is dangerous,
 * or because a better alternative exists.  Compilers warn when a
 * deprecated program element is used or overridden in non-deprecated code.
 *
 * @author  Neal Gafter
 * @since 1.5
 * @jls 9.6.3.6 @Deprecated
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

常见的,在我们的 java.util.lang 包下的 Date 中的 Date(String s) 构造器是被 @Deprecated 注解修饰了的。

在这里插入图片描述

在IDEA 中 如果我们调用了,被 @Deprecated 修饰的属性,方法,构造器,会给一个直观的将该属性/方法以删除线的方式显示处理并提示你建议使用别的方式替换 。如下

在这里插入图片描述

我们也可以自己写一个这样的被@Deprecated 修饰的属性/方法/类/构造器。举例如下:

在这里插入图片描述

5.3 @SuppressWarnings: 抑制编译器警告

在这里插入图片描述

@SuppressWarnings ** :指示应该在注解元素(以及包含在该注解元素中所有程序元素中的所有程序元素)中取消显示指定的编译器警告。换句话说:就是告诉编译器忽略此处代码产生的警告**。 注意是警告不是异常。

@SuppressWarnings的源码 ,可以看到该注解定义了一个名为 value 的属性。


package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

/**
 * Indicates that the named compiler warnings should be suppressed in the
 * annotated element (and in all program elements contained in the annotated
 * element).  Note that the set of warnings suppressed in a given element is
 * a superset of the warnings suppressed in all containing elements.  For
 * example, if you annotate a class to suppress one warning and annotate a
 * method to suppress another, both warnings will be suppressed in the method.
 *
 * <p>As a matter of style, programmers should always use this annotation
 * on the most deeply nested element where it is effective.  If you want to
 * suppress a warning in a particular method, you should annotate that
 * method rather than its class.
 *
 * @author Josh Bloch
 * @since 1.5
 * @jls 4.8 Raw Types
 * @jls 4.12.2 Variables of Reference Type
 * @jls 5.1.9 Unchecked Conversion
 * @jls 5.5.2 Checked Casts and Unchecked Casts
 * @jls 9.6.3.5 @SuppressWarnings
 */
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value();
}

举例: 这里我们定义一个 int num = 1 / 0 语句,IDEA 该我们提示了警告了。

在这里插入图片描述

当我们加上了 @SuppressWarnings IDEA 就没有这个警告了。如下:

在这里插入图片描述

在这里插入图片描述

具体的其他应用大家可以移步至:

标签:Java,warnings,suppress,value,注解,设计模式,annotation,属性
From: https://www.cnblogs.com/TheMagicalRainbowSea/p/17145556.html

相关文章

  • java中定义一个类可以同时继承两个类
    转载:百度知道(baidu.com)java中一个类不能直接继承两个类。比如说这样:classAextendsB,C不能这样写,因为java不支持多继承,但是可以像下面这样实现继承多个类:classAext......
  • Java里的对象是咋回事
    前言在上一篇文章中,壹哥给大家介绍了Java中的类及其特点、创建过程等内容,相信你现在已经知道该如何创建一个Java类了。接下来在本篇文章中,壹哥会继续带大家学习面向对象中......
  • Java的多线程+Socket
    客户端: packagecom.wulala;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net......
  • 解决java.lang.NoClassDefFoundError:Could not initialize class net.sf.cglib.beans
    异常描述项目引入Alibaba的EasyExcel工具,编译没有报错,在请求导出Excel文件的接口时,log异常出现以下错误java.lang.NoClassDefFoundError:Couldnotinitializeclassnet.......
  • Java常用类之Object源码分析
    一、概述理论上Object类是所有类的父类,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因此省略了extendsObject关键字。Object类属于java.lang包......
  • Java 调接口类似postman用form-data方式post传输数据
    转自JavaHttpClient发送multipartform-data的Post请求  publicstaticStringgateway(Stringparam,Stringparamvalue,Stringservicename,Stringinterface_id......
  • 如何通过Java 代码设置 Word 文档页边距
    页边距是指页面的边线到文字的距离。通常可在页边距内部的可打印区域中插入文字和图形,也可以将某些项目放置在页边距区域中(如页眉、页脚和页码等)。在我们用的Word文档中,都......
  • Java培训班学什么班型比较好
    了解互联网的同学应该都知道Java软件开发是比较热门的行业,学习的人也是络绎不绝,市面上的相关培训急剧增多,随着不同机构的成立,学习方式也不在是单一化的,在各式各样的教学方......
  • Java培训班出来能找到工作吗,能否直接就业!
    Java已经是世界上非常流行的编程语言,至今已经牢牢抓住了开发市场,现在的Java开发人才的需求量逐年增加,相对来说是很好找工作的,至于“Java培训班出来能找到工作吗”的问题,还......
  • Java编写监控指标并集成Prometheus、Grafana
    一、Pushgateway1、上传pushgateway-1.4.3.linux-amd64.tar.gz至/opt/soft/下载地址:https://github.com/prometheus/pushgateway/releases/download/v1.4.3/pushgate......