Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么Kotlin使用==表示结构相等,而引入===表示引用相等_Java_Kotlin_Reference_Equality_Structural Equality - Fatal编程技术网

Java 为什么Kotlin使用==表示结构相等,而引入===表示引用相等

Java 为什么Kotlin使用==表示结构相等,而引入===表示引用相等,java,kotlin,reference,equality,structural-equality,Java,Kotlin,Reference,Equality,Structural Equality,总的来说,Kotlin中的每一个设计决策都让人觉得它本身很好,并且提供了从Java的良好转换。作为一名Java开发人员,您可以开始在it中进行编码,将Kotlin看作是一个更简洁的Java,具有更少的样板文件,然后顺利地进入更高级的方面,如函数式编程 然而,我想知道的一件事是,为什么它的设计者决定让==的行为与的行为相同,然后引入==来进行参考等式检查。我可以想象,试图让其他Java开发人员加入进来,让他们看到您的Kotlin代码,然后想“哦,不,应该是equals调用的地方到处都有引用检查!”

总的来说,Kotlin中的每一个设计决策都让人觉得它本身很好,并且提供了从Java的良好转换。作为一名Java开发人员,您可以开始在it中进行编码,将Kotlin看作是一个更简洁的Java,具有更少的样板文件,然后顺利地进入更高级的方面,如函数式编程

然而,我想知道的一件事是,为什么它的设计者决定让
==
的行为与
的行为相同,然后引入
==
来进行参考等式检查。我可以想象,试图让其他Java开发人员加入进来,让他们看到您的Kotlin代码,然后想“哦,不,应该是equals调用的地方到处都有引用检查!”


离开Java约定的思维过程是什么?为了澄清这一点,我完全理解Kotlin中
=
equals
==
之间的区别,我只是想知道为什么。

主要原因可能是对象相等性的检查频率比对象标识的检查频率要高,所以至少应该同样容易。

我还没有看到关于这一点的明确声明。但是书中有一个由Kotlin团队成员编写的指针。第4.3.1节介绍了
==
操作符,首先描述了Java的比较,并说:

在Java中,有一种众所周知的做法,总是调用
equals
,还有一个众所周知的问题,就是忘记这样做

在Java中,检查对象标识很容易:

if (firstObj == secondObj)
但检查对象相等性的时间较长,而且不太清楚:

if (firstObj.equals(secondObj))
-或者更确切地说,如果您不想冒NullPointerException的风险:

if ((firstObj == null) ? (secondObj == null) : firstObj.equals(secondObj))
您可以看到,要输入并正确操作,要付出的代价要大得多。(特别是当其中一个对象是具有副作用的表达式时…)

因此,很容易忘记差异,或者不被打扰,而改用
=
(这可能会导致微妙、难以发现和间歇性的错误)

然而,Kotlin使最常见的操作变得更简单:它的
==
操作符使用
equals()
检查对象相等性,并负责空检查。这修复了Java的“忘记这么做的问题”

(尽管与Java代码的互操作性显然是一个主要目标,JetBrains并没有限制自己看起来像Java;Kotlin在可能的情况下借鉴了Java,但并不害怕将事情做得更好。您可以看到,在使用
val
var
以及声明的尾部类型时,不同的t默认范围和开放性,处理差异的不同方式,&c)


Kotlin的动机之一是修复Java中的许多问题(事实上,其中的JetBrains一开始就列出了“Kotlin中解决的一些Java问题”)因此,这似乎是这一变化背后的一个主要原因。

除了gidds的优秀答案之外,还有Java以外的其他语言对Kotlin产生了强烈的影响。特别是Scala和C#。引用(链接到InfoWorld,我不太喜欢,但这是我找到的最好的来源):

我们已经研究了所有现有的JVM语言,但没有一种能够满足我们的需求。Scala有正确的特性,但其最明显的缺陷是编译速度非常慢

显然,
=
是他们认为Scala正确的特性之一,因为它的工作原理完全相同(直到引用相等的名称,即Scala中的
eq

您可以在Scala的编程书中找到,Martin Odersky是该书的作者之一:

如第11.2节所述,相等的定义在Scala和Java中是不同的。Java有两个相等比较:==运算符,它是值类型和引用类型的对象标识的自然相等,以及equals方法,它是(用户定义的)引用类型的规范相等。此约定存在问题,因为更自然的符号==,并不总是与相等的自然概念相对应。在Java编程时,初学者的一个常见陷阱是将对象与==进行比较,而它们本应与相等进行比较。例如,比较两个字符串x和x在Java中,使用“x==y”的y很可能会产生false,即使x和y的字符顺序完全相同

Scala也有一个表示对象标识的相等方法,但使用不多。如果x和y引用同一个对象,则写为“x eq y”的这种相等是正确的。Scala中为“自然”保留==相等每个类型的相等。对于值类型,==是值比较,就像在Java中一样。对于引用类型,==与Scala中的相等相同。您可以通过重写总是从任何类继承的equals方法来重新定义新类型的==行为

另一方面,C#允许重载
==
而不是
Equals
,最终他们找到了一个语言设计者

长话短说的答案是,整个事情都很奇怪,而且两者都没有达到理想的效果


如果您不将其视为“从Java转换”,并将其视为自己的语言,那么问题就变成了“您为什么还要做其他事情?”团队成员编写的一本书中的这句话是一个很好的参考。关于空安全性的良好呼吁。对我来说似乎足够权威!TY!(顺便说一句,这是一本很棒的书;我通过三次阅读学习了这门语言。)我在书中或网站上找不到更明显的内容,因此这可能是最权威的来源——当然,除非JetBrains的任何人想发表评论,《Scala编程》是我读过的最好的技术书籍之一——这只是其中之一