Java 语言的最初设计者将“const”关键字作为保留字。但该术语仍未实现,而且很可能永远不会实现。这种情况让许多开发人员想知道为什么。
让我们更多地了解 Java 中的“const”关键字以及描述语言中常量的一些替代方法。
Java 中的“const”是什么意思?
任何看过 Java 中的“const”关键字的人都会从逻辑上假设其最初的意图是定义一个常量值。这个假设不会太离谱。
竞争语言 C 和 C++ 都使用“const”关键字,但这些语言并非纯粹面向对象。问题就在这里。在 Java 中,作为“const”的东西到底意味着什么?
保持不变是否意味着实例变量不会改变?
保持不变是否意味着类变量不会改变?
常量是否意味着对象的方法不能被覆盖?
保持不变是否意味着对象引用不会改变?
恒定是否意味着对象是不可变的?
考虑到上述所有问题,另一个大问题是如果一个对象仅在某些情况下是恒定的?
例如,某些语言允许“const”作为方法签名的一部分,这表明对象及其属性在方法内使用的短时间内不能更改。这有时被称为常量正确性。语言架构师在检查这些任务并试图确定“const”关键字的含义时,最终可能会陷入一个深深的兔子洞。
Java 的“final”与“const”关键字
在 Java 中最初可能使用“const 关键字”解决的许多用例使用 Java 的“final”关键字已经足够解决了。在 Java 中,“final”用于:
将原始值标记为常量;
表示方法不能被覆盖;
指定对象引用不能更改;
确保变量在方法中不变。
当“static”和“final”关键字组合时,可以使类级变量保持不变。虽然这并没有完全涵盖在其他语言中使用“const”关键字的所有不同场景,但它已经接近了。此外,将“静态”和“最终”组合在一起的选择为常量属性的行为方式提供了更大的灵活性,而不是仅使用一个关键字来尝试解决实例和类级别的语义。
当开发人员考虑语言通过允许将“static”和“final”关键字菊花链在一起而提供的功能和灵活性时,人们可能会推断 Java 中未实现“const”关键字的原因是因为它不需要。与 Java 中的“const”关键字的实现相比,“static”和“final”关键字的组合有效且可以说提供了一种更具表现力的方式来声明不变的变量。
不可变对象
就完全不可变的对象而言,历史上的解决方法是将实例变量声明为私有并通过公共 setter 和 getter 限制访问。最近,Java 引入了值类型的概念作为 JEP 169 的一部分。这将为该语言添加不可变、无引用的对象,并再次提供一种 Java 语言语法来实现许多与“const”相关的概念。
关于在 Java 中使用“const”关键字来实现 const 正确性的讨论始于 1999 年。但是,增强提案被拒绝为特性蠕变。语言架构师断言,在完全增量之后在 Java 中添加 const 实现——JDK 的长期支持版本已经推出——将导致代码膨胀,并且可能存在向后兼容性问题,从而完全扼杀了这个概念。从那以后,在 Java 中实现“const”关键字的想法就再也没有被重新审视过。
Java 中的 const 关键字不能在不导致编译时错误的情况下使用。
为什么“const”没有在 Java 中实现?如果没有实现它的意图,为什么要让const成为保留字呢?
一个可能的原因是避免混淆。如果“const”不是保留字,则允许开发人员使用该短语来命名变量。试想一下,对于学习使用“const”实现的语言进行编程的 C++ 和 JavaScript 开发人员来说,这可能会造成多大的困惑。简单地将 Java 中的“const”关键字设为保留字有助于避免任何混淆。
为什么 Java 中的“const”是没有实现的保留字?
同样,这主要是为了避免混淆。其他关键字提供了等效的功能,并且因为该概念不适合面向对象的范例。或者用外行的话来说,Java 不需要它。
在大多数情况下,因为 JDK 不需要它,“const”在 Java 中没有实现。其他语言特性提供声明常量或提供不变性的能力。该语言的提供者希望避免混淆,并决定即使是善意的开发人员也不能在他们的代码中使用该术语。