java类库的废弃API

java语言一直在进化,java类库也越来越庞大,给人的感觉是一直在做加法。

有没有做减法呢?当然也有,一些是设计失误需要撤回的,如可能引起线程安全问题的Thread.stop()等方法;还有是随着时代发展而被淘汰的,比如曾被寄予厚望的Applet。

java类库中这些废弃的内容有没有地方统一归档,方便我们的查找?假如我们要升级java版本,而找出当前代码中使用了哪些新版本废弃的API,就能让准备更加充分。

答案是有的。

java9之后的java API文档,贴心地单独为废弃的内容做了一个页面。如java 21版本对应的链接是 Deprecated List (Java SE 21 & JDK 21)

顶上有个过滤功能,可以按特定版本来分别过滤该版本废弃了哪些,其中的others选项包含了11之前所有版本的废弃内容。

接下来是目录,根据类型分为接口、(非异常)类、异常类、字段、方法、常量、枚举常量这七种。而最上面的终将废弃( Terminally Deprecated),和下面的七种并不是并列关系,而是将下面七种类型中最终会被删除的部分提取(复制)出来,单独放在这里。

为什么这样做?因为废弃的含义分为两种,一种是后续版本要删除的(即终将废弃),如果你的代码使用了这样的API,如果后续升级类库,你的代码就可能无法通过编译。而另一种是不会删除的API,但不建议你使用,后续版本也会保留,升级类库不会编译失败。作为类库的用户,显然更关注第一种,所以就单独放了一份。(更多可参考 JEP 277: Enhanced Deprecation

接下来就是具体的内容,分别是名称、版本号和描述,并支持按名称或版本号进行排序。按版本号排序很实用,描述的内容也值得参考,里面会提供废弃的原因,是否有替代品等信息。

简单地浏览一部分:

终将废弃并删除的

java.lang.Thread.stop() 等

还有resume、suspend 以及 ThreadGroup类对应的方法。早在1.2就废弃了。

参考 Java Thread Primitive Deprecation (Java SE 21 & JDK 21) (oracle.com)icon-default.png?t=N7T8https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html

java.applet.Applet等

java9废弃,早就没人用了

java.lang.Boolean(boolean) 等构造函数

还有Byte、Character、Double等基本类型的包装类,它们的构造函数都在java 9废弃了。改用静态工厂方法,可以参考 Effective Java 的第一条建议。

java.lang.Object.finalize()

一直没存在感的方法终于在java 9 废弃了,减少了记忆学习的负担。虽然这里建议改用 Cleaner,但 Effective Java 3 第八条告诉我们,Cleaner最好也别去碰。

javax.security.cert.Certificate 等

其实是转正了,包名从 javax... 换成了 java.security.cert 。可见网络安全的地位从可选变成了必选。java 9 废弃。

java.lang.SecurityManager 及其相关

java 17废弃。这安全也是当年java的一大卖点,现在也没落了。

这个的确很少用,页面中给出了废弃原因的链接: JEP 411

主要就是说,一是用于客户端代码安全,但Servlet早就没人用了;二是用于服务端代码安全,可实际上基本没什么人用。

java类库越来越大,要管的东西太多,我们维护起来太累,放弃了。

另外2020年CWE的top 25安全漏洞,Security Manager有19个都管不了,还要它干嘛?(感觉这个有点强词夺理,也没指望人一个机制能解决所有层面上的漏洞)

发明了20多年,但业界太少人用了,除了少量软件如ElasticSearch和Tomcat。

甚至.NET都不支持了,java废弃它的理由就更充分啦。

废弃但不删除的

java.util.Observer 接口 和 java.util.Observable 类

java9 废弃,理由是功能太局限。

如果要更丰富的事件模型,用 java.beans包。如果要可靠有序,用 java.util.concurrent 包。如果要用响应式流风格编程,用 Flow API。

java.util.Date.getDate() 等方法

从1.1版本起就废弃了。

废弃的有 get/set 年月日时分秒等方法,以及转换成字符串的方法。废弃的原因是这些api不支持国际化。所以要获取年月日等信息,要用Calendar类;而格式化或者日期解析,要用 DateFormat类。

Date类本身剩下的非废弃方法就两三个,只能用于比大小,功能非常有限,感觉类似于废弃。构造函数只剩两个,一个是无参,根据当前时间构造对象,另一个是long毫秒数为参数。还有个java 8加入的静态工厂方法,根据Instant对象生成Date对象。

java.lang.Class.newInstance() 方法

java 9废弃。这个方法用来调用某个类的无参构造器,如果构造器有异常,则newInstance方法会原样抛出来。但newInstance方法本身只声明了两个 checked 异常:InstantiationException 和 IllegalAccessException。这个和java语言规定的“方法必须声明所有自己可能抛出的checked异常”就矛盾了,等于绕过了编译器的校验。

建议改用 Constructor.newInstance  方法,它会把构造器的异常包装成 InvocationTargetException 抛出来,而且也在方法中声明了。

java.lang.Runtime.exec(String)等方法

java 18废弃。并不是所有exec都废弃了,只是废弃了其中几个容易出问题的:

java.lang.Thread.getId()

java19废弃。因为它不是final,可能被覆写。现在加final又太迟了。建议改用 Thread.threadId()。

java.util.Locale的构造器

所有构造器全部在java 19废弃了。替代方式有很多,比如 Local.Builder,还有两个静态工厂方法,或者常量,以及匹配/过滤/查找等方法。

java.net.URL的构造器

所有构造器全部在java 20废弃了。改用URI或URL的一些静态工厂方法。

补充

jdeprscan

相比看文档,想知道当前项目里用了哪些废弃的java类库API,更精确的方法是使用 jdeprscan ,具体可以参见 The jdeprscan Command (oracle.com)

javadoc

新版本的javadoc也支持生成“废弃”页面。比如写这样一个类:

/** @deprecated useless class */
@Deprecated(since="11", forRemoval=true)
public class Hello {

    /** @deprecated useless method */
    @Deprecated(since="9", forRemoval=true)
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getId());
    }
}

然后执行 

javadoc Hello.java

打开生成的api文档,可以看到

不过相比Oracle提供的文档,我们的文档少了两部分,一是顶部按版本过滤的复选框,二是表格中的版本列。也许是Orcale做了定制,还需要再研究下。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值