本文旨在解決 java 密封類 (sealed class) `permits` 子句中涉及泛型類型參數(shù)導(dǎo)致的編譯錯誤。核心問題在于 `permits` 子句要求列出的是類型名稱 (typename),而非包含泛型參數(shù)的類類型 (classtype)。文章將詳細解釋這一規(guī)范,提供正確的代碼示例,并闡述不同 java 編譯器 (如 `javac` 和 `ecj`) 在處理此語法時的差異,幫助開發(fā)者避免和解決相關(guān)編譯問題。
Java 17 引入的密封類(Sealed Class)特性允許開發(fā)者對類的繼承或接口的實現(xiàn)進行更嚴格的控制。通過 sealed 關(guān)鍵字,一個類或接口可以聲明其允許被哪些特定的子類或?qū)崿F(xiàn)類繼承或?qū)崿F(xiàn)。這些被允許的子類或?qū)崿F(xiàn)類必須在 permits 子句中明確列出。
permits 子句的語法旨在提供一個清晰的、可枚舉的列表,表明哪些類型是密封類或接口的直接已知子類。然而,在使用泛型時,開發(fā)者可能會遇到一個常見的編譯陷阱。
當密封類本身是泛型類,并且其允許的子類也是泛型時,直觀上可能會認為需要在 permits 子句中包含泛型類型參數(shù)。例如,考慮以下結(jié)構(gòu):
public sealed abstract class APath<R> permits APath<R>.LastWildcard<R>, APath<R>.WholeWildcard<R> { protected final List<ADir> dirs; public final class LastWildcard<R1> extends APath<R1> { // ... } public final class WholeWildcard<R1> extends APath<R1> { // ... } } public sealed abstract class ADir permits ADir.Wildcard, ADir.Dir { public final class Wildcard extends ADir {} public final class Dir extends ADir {} }
在這種情況下,Maven 使用 javac 編譯器進行編譯時,會報告一系列錯誤,其中第一個錯誤通常指向 permits 子句中泛型類型參數(shù)的位置,例如:
立即學(xué)習(xí)“Java免費學(xué)習(xí)筆記(深入)”;
[ERROR] /D:/Experiment/src/main/java/prefile/pref/APath.java:[13,52] '{' expected [ERROR] /D:/Experiment/src/main/java/prefile/pref/APath.java:[15,25] class, interface, enum, or record expected
這些錯誤信息看起來可能令人困惑,但其根本原因在于 permits 子句對泛型參數(shù)的語法要求與 extends 或 implements 子句不同。
根據(jù) Java 語言規(guī)范(JLS),permits 子句中列出的是類型名稱 (TypeName),而不是類類型 (ClassType)。這意味著在 permits 子句中,我們應(yīng)該只使用類的簡單名稱或完全限定名,而不應(yīng)包含任何泛型類型參數(shù)。
因此,即使 APath 及其子類 LastWildcard 和 WholeWildcard 都是泛型類型,在 permits 子句中也必須省略泛型參數(shù)。
正確的代碼示例:
public sealed abstract class APath<R> permits APath.LastWildcard, APath.WholeWildcard { protected final List<ADir> dirs; public final class LastWildcard<R1> extends APath<R1> { // ... } public final class WholeWildcard<R1> extends APath<R1> { // ... } }
通過移除 permits 子句中的泛型類型參數(shù) (<R> 和 <R1>),代碼將符合 Java 語言規(guī)范,并能順利通過 javac 編譯。
在開發(fā)過程中,您可能會發(fā)現(xiàn)某些集成開發(fā)環(huán)境(IDE),如 Eclipse 或基于 Eclipse LSP 的 VSCode Java 插件,并不會立即報告上述錯誤。這通常是因為這些 IDE 使用了不同的 Java 編譯器。
這種編譯器行為上的差異解釋了為什么在 IDE 中代碼看起來沒有問題,但在使用 Maven 構(gòu)建時卻出現(xiàn)編譯錯誤。因此,始終以 javac 的行為為準,并確保代碼嚴格符合 Java 語言規(guī)范,是保證項目可移植性和正確性的最佳實踐。
通過理解 permits 子句的精確語法要求以及不同編譯器之間的潛在差異,開發(fā)者可以更有效地使用 Java 密封類,避免常見的編譯錯誤,并構(gòu)建出健壯、符合規(guī)范的 Java 應(yīng)用程序。
以上就是解決 Java 密封類 permits 子句中的泛型編譯問題的詳細內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個人都需要一臺速度更快、更穩(wěn)定的 PC。隨著時間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺進程會占用資源并降低性能。幸運的是,許多工具可以讓 Windows 保持平穩(wěn)運行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號