Answers:
每次我从繁琐的C ++编码过渡到Java时,都要花一些时间来适应Java中缺乏const正确性的问题。const
如果您不知道,C ++中的这种用法与仅声明常量变量有很大不同。本质上,它可以确保通过特殊类型的指针(称为const-pointer)进行访问时对象是不可变的。仅包含不应有副作用的方法。不幸的是,这不是由语言强制执行的。
维基百科提供了有关该主题的以下信息:
有趣的是,Java语言规范将const视为保留关键字(即,不能用作变量标识符的关键字),但未为其分配任何语义。据认为,关键字的保留是为了允许Java语言的扩展以包括C ++样式的const方法和指向const类型的指针而发生的。Java社区流程中用于在Java中实现const正确性的增强请求票证于2005年关闭,这意味着const正确性可能永远不会进入正式的Java规范。
final
与此类似。
final
例如,该方法的工作方式与C ++ const
方法完全不同。
final
关键字仅确保将属性或变量仅分配一次。例如,仍然可以通过调用某些具有副作用的方法来更改该对象的状态。就引用对象而不是指针而言,C ++的堆栈分配有点类似,但这就是全部。当然,这是dom0已经说过的内容。final
final
Java const
中的值类型似乎像C ++一样工作,但是T&
对于引用类型而言,它更像是C ++非常量
const
含义是什么,
首先,意识到“ const”关键字的语义对不同的人意味着不同的含义:
final
语义-不能重新分配引用变量本身以指向另一个实例(内存位置),但实例本身是可修改的const
指针/引用语义-表示该引用不能用于修改实例(例如,不能分配给实例变量,不能调用可变方法)-仅影响引用变量,因此指向该变量的非常量引用同一实例可以修改该实例为什么或者为什么不const
其次,如果你真的想深入到一些“亲”与“骗子”的论点,看到这个请求增强(RFE)“错误”下的讨论。此RFE请求“只读参考”类型的“常量”功能。“ const”主题于1999年开放,之后于2005年被Sun关闭/拒绝,因此引起了激烈的辩论:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070
尽管双方都有很多好的论据,但反对的一些经常被引用的理由(但不一定是令人信服或明确的理由)const
包括:
const
平均值以上)在有人试图就这些原因是好是坏之前就我进行辩论之前,请注意这些不是我的原因。它们只是我从RFE讨论中收集到的某些原因的“要点”。我本人不一定同意他们的意思-我只是想列举为什么有些人(不是我)可能觉得const
关键字可能不是一个好主意。我个人希望以明确的方式将更多的“ const”语义引入语言。
volatile
这么简单的理解吗?还是final
?嗯
const
在C ++中,并不意味着值是一个常数。
const
在C ++中,C ++意味着合同的客户承诺不改变其价值。
const
如果您在支持基于线程的并发的环境中,则表达式的值是否更改会变得更加明显。
由于Java从一开始就设计为支持线程和锁并发,因此它不会因重载术语以使其具有语义而增加混乱final
。
例如:
#include <iostream>
int main ()
{
volatile const int x = 42;
std::cout << x << std::endl;
*const_cast<int*>(&x) = 7;
std::cout << x << std::endl;
return 0;
}
输出42然后7。
尽管x
标记为const
,因为创建了非常量别名,但x
它不是常量。并非每个编译器都需要volatile
这种行为(尽管每个编译器都可以内联常量)
对于更复杂的系统,您无需使用即可获得const / non-const别名const_cast
,因此养成以为const表示不会改变的习惯变得越来越危险。const
仅仅意味着您的代码在没有强制转换的情况下无法更改它,而不是值是恒定的。
const
,并不意味着值是恒定的。这意味着值的客户被约束不能对其进行更改。在您的示例中,没有别名,因此所有用户都受到相同的约束。通常情况并非如此。const
影响客户,而不是价值-它表示您无法更改,而不是它不会更改。
immutable interface
和immutable object
另一种方式(可打击与演员和反射)在Java中模仿常量。可以使用SealedObject完成“ True” const ,因为它破坏了我们对象的用例。
这是一个古老的问题,但是自从今天这个话题出现以来,我还是想贡献我的2美分。
这不能完全回答为什么没有const?但是如何使您的班级一成不变。(不幸的是,我还没有足够的声誉来发表对此已接受答案的评论)
保证对象不变的方法是更仔细地将类设计为不变。这比可变类需要更多的注意。
这可以追溯到Josh Bloch的有效Java 项目15-最小化可变性。如果您还没有读过这本书,请拿起副本并阅读几次,我保证它将使您的比喻性“ java游戏”更有趣。
在第15项中,Bloch建议您应限制类的可变性,以确保对象的状态。
要直接引用该书:
不可变类只是其实例无法修改的类。每个实例中包含的所有信息在创建时都会提供,并且在对象的生命周期内是固定的。Java平台库包含许多不可变的类,包括String,装箱的原始类以及BigInteger和BigDecimal。这样做的原因有很多:不可变类比可变类更易于设计,实现和使用。它们不太容易出错,并且更安全。
然后,Bloch通过遵循5条简单规则来描述如何使您的类不可变:
final
)。final
。private
。有关更多详细信息,我强烈建议您拿起这本书的副本。
有一种方法可以在Java中创建“ const”变量,但仅适用于特定类。只需定义一个具有最终属性的类并将其子类化即可。然后在要使用“ const”的地方使用基类。同样,如果需要使用“ const”方法,请将其添加到基类中。编译器不允许您修改它认为是基类的最终方法的内容,但会读取和调用子类上的方法。
您可以使用static final来创建类似于Const的东西,我过去曾经使用过。
protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;
public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;
const
关键词,但没有基本的功能。相应地更正了您的标题和标签。