比 Java 更强大的 kotlin.Deprecated

article/2025/11/10 18:59:30

我们都知道 Java 有一个java.lang.Deprecated注解,用来将一个 API 标记为“废弃”,或者说“不建议使用”。比如 String 类就有一个被标记为 Deprecated的构造函数:

@Deprecated
public String(byte ascii[], int hibyte) {this(ascii, hibyte, 0, ascii.length);
}

Java 还提供了一个 @deprecated 的文档标签,用于提供相关信息。

这个注解存在几个缺陷:

  • 无法禁止使用废弃的 API,单单一个编译警告不可能阻止划水程序员;
  • 无法提供足够的信息,为什么这个 API 被废弃了?需要用哪个 API 代替?毕竟文档注释不是强制性的。

对于这个问题,Kotlin 的解决方案是 kotlin.Deprecated 注解,它比 java.lang.Deprecated更强大、更人性化。

kotlin.Deprecated的声明如下:

@Target(CLASS, FUNCTION, PROPERTY, ANNOTATION_CLASS, CONSTRUCTOR, PROPERTY_SETTER, PROPERTY_GETTER, TYPEALIAS)
@MustBeDocumented
public annotation class Deprecated(val message: String,val replaceWith: ReplaceWith = ReplaceWith(""),val level: DeprecationLevel = DeprecationLevel.WARNING
)
  • @Target 表示 Deprecated可以用在类、函数、属性、注解类、构造函数、getter、setter 和类型别名上;
  • @MustBeDocument表示Deprecated是个公开的 API,必需包含在 API 文档里。

我们重点看三个参数:

第一个参数很简单,String 类型的 message,需要在这里说明废弃的原因。

@Deprecated("this function is deprecated!")
fun oldAdd(a: Int, b: Int) {println(a + b)
}fun main(args: Array<String>) {oldAdd(1, 2)
}

比如我们定义了上面的函数 oldAdd,用 Deprecated 标注一下,如果调用这个函数,就会出现编译警告:

Warning:(7, 5) Kotlin: ‘oldAdd(Int, Int): Unit’ is deprecated. this function is deprecated!

我们定义 Deprecated 时给的 this function is deprecated! 出现在了警告信息里,让我们排查问题方便不少。

第三个参数是DeprecationLevel这个枚举里定义的三个废弃级别之一,在使用了 Deprecated API 的地方给出不同级别的警告 :

public enum class DeprecationLevel {WARNING,ERROR,HIDDEN
}
  • WARNING:默认选项,编译依然会成功,但会出现编译警告;
  • ERROR:编译错误,相当于禁止使用这个 API;
  • HIDDEN:隐藏,无法调用这个 API。

我们把上面的代码改一下,加上自定义的废弃级别:

@Deprecated("this function is deprecated!",ReplaceWith(""), // 无法省略level = DeprecationLevel.ERROR
)
fun oldAdd(a: Int, b: Int) {println(a + b)
}

再编译就会出现编译错误,编译直接失败:

Error:(11, 5) Kotlin: Using ‘oldAdd(Int, Int): Unit’ is an error. this function is deprecated!

如果换成HIDDEN

Error:(11, 5) Kotlin: Unresolved reference: oldAdd

找不到这个函数了……

最后是第二个参数,需要是 ReplaceWith 类型,它是一个注解类型(因为注解的参数只能是基本类型、String 和注解类型)。声明如下:

@Target()
@Retention(BINARY)
@MustBeDocumented
public annotation class ReplaceWith(val expression: String, vararg val imports: String)
  • expression 是要替换成的代码段,智能替换参数;
  • imports 是需要额外 import 的依赖。

定义一个函数newAdd,放进new包里:

package newfun newAdd(a: Int, b:Int) {println("$a + $b = ${a + b}")
}

然后修改一下oldAdd 函数:

@Deprecated("this function is deprecated!",ReplaceWith("newAdd(a, b)", "new.newAdd")
)
fun oldAdd(a: Int, b: Int) {println(a + b)
}

这样,我们在 IDEA 里就可以按 Alt + Enter 一键替换:
在这里插入图片描述
替换时会自动匹配参数,并导入 imports 中定义的依赖:
在这里插入图片描述

原文链接:https://zhuanlan.zhihu.com/p/32890550


http://chatgpt.dhexx.cn/article/OIgfSUBo.shtml

相关文章

Android IntentService deprecated|笔记

先回顾一下&#xff0c; 面试一般都喜欢问IntentService 原理&#xff0c; 个人觉的啥是原理&#xff0c;不就是源码吗&#xff1f; 就下面几行源码&#xff0c;就能出滋生出来&#xff0c;几道面试题&#xff1a; 什么IntentService继承service阿&#xff0c;自带looper阿&…

java 注解 @Deprecated

目录 一 笔记二 Deprecated 源码三 定义一个已过时的类 AnnotationTest03_User.java四 使用自定义的过时注解类 一 笔记 Deprecated 可以标注很多元素&#xff1a;类、接口、方法、属性。。。。。。 这个注解也是给编译器看的&#xff0c;也是做编译检查的&#xff1b;被这个…

JAVA后台开发提升注解篇 @Deprecated

前期说明 先说明下&#xff0c;这个注解不加&#xff0c;对代码没有任何影响。 加了的话&#xff0c;会让调用端的人觉得你比较上道。 这是为什么呢&#xff1f; 我们先来简单聊下 Deprecated这个注解。 Deprecated注解 作用域&#xff1a;类、方法或者属性上 格式如下 …

@Deprecated注解

刚学到一个注解 Deprecated 表示这个方法下个版本可能会被弃用 看个东西 /** deprecated */Deprecatedpublic static boolean isEmpty(Nullable Object str) {return str null || "".equals(str);}这是 springframework 下的一个方法 StringUtils.isEmpty() 然后…

deprecated注释 原因

Deprecated 标记下线接口或者属性的时候&#xff0c;希望能够说明下线原因及新的方法地址 可以使用注释 /*** deprecated 我为什么要下线这个字段或者方法&#xff0c;替代的字段或者方法是 {link com.example.demo.SimpleCache.CacheObj#longData}*/Deprecatedprivate BigDe…

deprecated的用法

deprecated的用法:在java中用deprecated标志该方法过时 实例:有如下方法 public Collection getUserPropList(String userId, String systemId,String valueType) throws Exception ... { .... String filter ""; filter "USER_ID" userId …

【Java】Deprecated 注解

1. Deprecated 注解 Deprecated: 用于表示某个程序元素(类&#xff0c;方法等)已过时如果使用 Deprecated 去修饰一个类&#xff0c;表示这个类已经过时了&#xff0c;但过时不代表不能用了&#xff0c;即不推荐使用&#xff0c;仍然可以使用 public class Deprecated_ {publ…

Linux命令之grep命令

一、命令介绍 grep命令是文本搜索命令&#xff0c;它可以正则表达式搜索文本&#xff0c;也可从一个文件中的内容作为搜索关键字。grep的工作方式是这样的&#xff0c;它在一个或多个文件中搜索字符串模板。如果模板包括空格&#xff0c;则必须被引用&#xff0c;模板后的所有字…

grep与egrep

个人觉得egrep比较好用&#xff0c;感觉改良了grep的一些不可以直接操作的东西&#xff0c;但是总体来说还是没太大区别的&#xff0c;都是一个过滤工具。 grep 和 egrep 都要通过 正则表达式来筛选我们想要的东西&#xff0c;只能筛选文本内容&#xff0c;不能对目录筛选&…

Linux grep/egrep命令详解

grep命令是一种强大的文本搜索工具&#xff0c;它能使用正则表达式搜索文本&#xff0c;并把匹 配的行打印出来 grep搜索成功&#xff0c;则返回0&#xff0c;如果搜索不成功&#xff0c;则返回1&#xff0c;如果搜索的文件不存在&#xff0c;则返回2。 grep的规则表达式&…

如何在 Linux 中使用 ripgrep (rg) 命令?

ripgrep是开源社区正在进行的 RIIR&#xff08;用 Rust 重写&#xff09;努力的一个优秀成果。&#xff0c;它旨在成为经典grep 命令的高级替代品。 使用 ripgrep 的语法如下&#xff1a; rg <pattern> [files/directories]使用 ripgrep&#xff0c;无需提及文件名。如…

Linux常用命令——grep(*)

grep 文本过滤工具 语法格式&#xff1a;grep 【options】【pattern】【file】 grep [参数] [匹配模式] [查找的文件] 注意&#xff1a; 1.grep 是 Linux 系统中最重要的命令之一&#xff0c;其功能是从文本文件或管道数据流中筛选匹配的行及数据。 2.grep 命令里的匹配模式或模…

Linux常用命令——grep

grep 文本过滤工具 语法格式:grep 【options】【pattern】【file】 grep [参数] [匹配模式] [查找的文件]注意:1.grep 是 Linux 系统中最重要的命令之一,其功能是从文本文件或管道数据流中筛选匹配的行及数据。2.grep 命令里的匹配模式或模式匹配,都是你要好找的东西,可以…

【Linux】grep 命令详解

文章目录 一、grep常用命令1、语法2、范例 二、grep的一些高级参数1、语法2、范例 三、基础正则表达式练习1、与中括号 [] 结合2、与反向选择^结合使用3、与行首 ^ 和行尾 $ 字符结合4、任意一个字符 . 与重复字符 * 5、 {} 限定连续字符范围 一、grep常用命令 grep的功能是分…

【WINDOWS / DOS 批处理】for命令详解(八)

for命令详解&#xff08;一&#xff09;【共十篇】 for命令详解&#xff08;二&#xff09;【共十篇】 for命令详解&#xff08;三&#xff09;【共十篇】 for命令详解&#xff08;四&#xff09;【共十篇】 for命令详解&#xff08;五&#xff09;【共十篇】 fo…

【WINDOWS / DOS 批处理】for命令详解(一)

for命令详解&#xff08;一&#xff09;【共十篇】 for命令详解&#xff08;二&#xff09;【共十篇】 for命令详解&#xff08;三&#xff09;【共十篇】 for命令详解&#xff08;四&#xff09;【共十篇】 for命令详解&#xff08;五&#xff09;【共十篇】 fo…

批处理 bat for 详解

一、前言 在批处理中&#xff0c;for是最为强大的命令语句&#xff0c;它的出现&#xff0c;使得解析文本内容、遍历文件路径、数值递增/递减等操作成为可能&#xff1b;配合if、call、 goto等流程控制语句&#xff0c;更是可以实现脚本复杂的自动化、智能化操作&#xff1b;合…

批处理for循环命令初步学习

1 基本格式 DOS批处理for循环语句的基本格式是&#xff0c; for /参数 %变量 in (集) do 命令 参数&#xff1a;FOR分四种参数 D L R F&#xff1b; 变量&#xff1a;变量名是由单个字母组成且区分大小写&#xff08;原帮助是这么说的&#xff0c;实际运用中用单个数字作为…

BAT批处理文件 for命令详解

Windows bat脚本的for语句基本形态如下&#xff1a; 在cmd窗口中&#xff1a;for %I in (command1) do command2 在批处理文件中&#xff1a;for %%I in (command1) do command2之所以要区分cmd窗口和批处理文件两种环境&#xff0c;是因为在这两种环境下&#xff0c;命令语句…

jenkins配置中执行 ant 命令时,提示找不到ant 命令

1.在服务器上手动执行ant &#xff0c;则可以正常执行&#xff0c;但是使用jenkins 构建时却提示无法识别ant命令 查询了相关原因为&#xff1a;jenkins默认情况下执行shell脚本是使用非登录方式&#xff0c;然而非登录方式不会加载 /etc/profile 文件&#xff0c;且ant_home 此…