儘管Java 是我使用過的向後相容程度最高的語言和環境之一,但始終存在功能棄用甚至刪除的可能性。 Java 21 將棄用兩個功能,這就是我們今天要討論的內容。
棄用程式碼或功能意味著不鼓勵使用它,並且可能在未來的版本中不再存在。為什麼不鼓勵它可能有很多原因。
棄用的最常見原因是:
無論根本原因為何,已棄用的功能仍然是系統的一部分,因此仍然可用,最起碼到現在。
JEP449旨在棄用 Windows 的 32 位元 x86 支持,最終目標是在將來完全刪除它。
這種棄用及其未來刪除背後的原因主要是技術性的。
為任何系統提供軟體總是需要決定您實際上想要支援哪些平台。針對不再受支援的平台或版本是可能的,但通常意味著增加支援工作、向後移植、自行修復內容等。
以Windows平台為例,最後一個32位元版本於2020年發布,官方支援於2025年10月結束。
如果您知道 64 位元 Windows 如何處理 32 位元應用程序,您可能想知道為什麼不能透過 Windows整合的 WOW64 模擬層來運行 JVM ?嗯,通常可以以這種方式運行應用程序,但性能會急劇下降。
這就是OpenJDK 團隊決定繼續棄用的原因,因為它只會影響 Java 的未來版本。舊系統仍然可以使用刪除先前的所有 Java 版本。
Java 21 中的一項直接變更會影響 JDK 的建置過程,因為預設會停用配置建置的可能性。嘗試執行bash ./configure會出現錯誤:
...checking compilation type... nativeconfigure: error: The Windows 32-bit x86 port is deprecated and may be removed in a future release. \Use --enable-deprecated-ports=yes to suppress this error.configure exiting with result code 1
由於功能只是被棄用,而不是被刪除,因此OpenJDK 團隊新增了新的設定選項(如錯誤所示),--enable-deprecated-ports=yes以仍允許配置。但是,會發出警告以強調棄用和未來可能的刪除。
$ bash ./configure --enable-deprecated-ports=yes...checking compilation type... nativeconfigure: WARNING: The Windows 32-bit x86 port is deprecated and may be removed in a future release....Build performance summary:* Cores to use: 32* Memory limit: 96601 MBThe following warnings were produced. Repeated here for convenience:WARNING: The Windows 32-bit x86 port is deprecated and may be removed in a future release.
Java 21 充滿了令人敬畏的新功能,虛擬執行緒 (JEP 444)的新增就是其中之一。它引入了輕量級(虛擬)線程,這可能會透過減少編寫、維護和觀察此類應用程式所需的工作量,從而顯著改變我們處理 Java 中高吞吐量並發應用程式的方式。它們的開銷比傳統平台(核心)執行緒少得多
然而,在 Windows 32 位元 x86 上,由於技術限制,此功能必須回退到核心執行緒。底層平台的這種缺失功能通常是未來棄用和刪除的強大指標。
儘管如此,您仍然可以編寫和使用新的執行緒程式碼,但在實際操作中卻缺少預期的好處。
如您所看到的,棄用是有道理的,因為 Windows 32 位元 x86 無論如何都無法運作。此外,針對特定平台進行建置仍然是可能的,只是目前不鼓勵這樣做。因此,如果您仍然需要支援遺留系統並知道您在做什麼以及後果是什麼,您仍然可以使用它。
代理程式使用Instrumentation API透過變更 JVM 中已載入的字節碼來修改現有應用程式。這使您能夠更改應用程式的行為,而無需實際更改其原始程式碼。它通常用於分析器和監視工具(例如Datadog和YourKit)、面向方面的程式設計等等。
有兩種方法可以載入代理,一種是透過新增參數或呼叫來靜態加載,另一種是透過運行如下程式碼從另一個應用程式動態載入:-javaagent:agent-to-load.jar-agentlib:optionsjava
#import java.lang.management.ManagementFactory;import com.sun.tools.attach.VirtualMachine;public class DynamicAgentLoader {public static void main(String... args) {int pidOfOtherJVM = ...;File agentJar = ...;try {VirtualMachine vm = VirtualMachine.attach(pidOfOtherJVM);vm.loadAgent(agentJar.toAbsolutePath);// ... do your workvm.detach();} catch (Exception e) {// ...}}}
第一個選項問題不大。這是對 JVM 代理的明確且有意的使用。然而,後者是間接的,並且可能不受所連接的 JVM 的控制。
Java 平台默认致力于实现完整性,为我们构建应用程序提供强大而坚实的基础。代理的设计考虑到了最好的意图,为您提供(良性)工具的力量。然而,为了确保这种完整性,通过(动态)代理进行检测是一个大问题,因为它们超出了您的直接控制范围,并且可能会对您的应用程序造成严重破坏。这就是为什么您作为应用程序的所有者必须对允许和加载哪些代理做出有意识且明确的决定。
插播一条,如果你近期准备面试跳槽,建议在ddkk.com在线刷题,涵盖 1万+ 道 Java 面试题,几乎覆盖了所有主流技术面试题,还有市面上最全的技术栈500套,精品系列教程,免费提供。
在Java 21 中,您仍然可以加载动态代理,但 JVM 会生成多个警告,通知您潜在的问题以及如何隐藏这些警告:
WARNING: A {Java,JVM TI} agent has been loaded dynamically (file:/path/to/agent.jar)WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warningWARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more informationWARNING: Dynamic loading of agents will be disallowed by default in a future release
未来的Java 版本将默认禁止加载动态代理,并且任何使用Attach API都会引发异常:
com.sun.tools.attach.AgentLoadException: Failed to load agent library: \Dynamic agent loading is not enabled. Use -XX:+EnableDynamicAgentLoading \to launch target VM.
异常消息包括启用动态代理加载所需的步骤:参数-XX:+EnableDynamicAgentLoading。因此,如果您有意识地决定允许动态代理,那么您仍然可以。
到目前为止,仅发出警告。但是,您可以完全禁止动态加载 Java 代理。您可以通过使用将(加号)与(破折号/减号)-XX:-EnableDynamicAgentLoading交换的参数来执行此操作,以强化您的应用程序或为即将到来的更改做好准备。+-
本文中提到的两个功能的弃用对我来说是有道理的。
Windows 10 32 位 x86 支持是一项技术债务,阻碍了创新,例如利用虚拟线程的全部功能。
动态加载代理严重损害了 Java 平台的完整性,并且存在潜在的安全风险。如果打击者“足够接近”可以连接到另一个 JVM,那么您可能会遇到更大的问题。
尽管如此,我们始终必须意识到将来可能会发生变化或删除的内容,因为我们很可能无法决定它何时发生。Java 通常对弃用和删除时间框架相当慷慨,某些功能可能会弃用数十年,但看不到删除的迹象。所以很自然地,我们是否应该使用已弃用的 API 的问题就出现了。
在我看来,如果可能的话,我们应该尽量避免使用已弃用的 API。随着时间的推移,它正在成为技术债务,最终必须偿还。没有什么比因为不相关的原因而需要升级代码更有压力的了,而且您多年来依赖的一些已弃用的功能最终被删除,使得升级方式比需要的更加复杂。
以上是別再亂用了,Java 21 將棄用、刪除這些功能!的詳細內容。更多資訊請關注PHP中文網其他相關文章!