为什么Java需要双等号?

8

为什么在使用if语句比较整数时,Java需要一个双等号(==)?

例如:

if(x = 3.141)
     System.out.println("x is equal to pi.");

内容不正确,应该是

if(x == 3.141)
     System.out.println("x is equal to pi.");

我知道"=="用于比较整数,"="用于设置整数值,但为什么在if语句中这个规则仍然成立?

if语句中分配变量值(或初始化新变量)是否允许?

任何人会想在if语句中给变量分配新值吗?(如果有,请提供一个例子。)

这似乎是一个应该已经有答案的问题,但我无法在这里或使用谷歌找到答案,如果这是重复的问题,请告诉我,我会立即删除它。

8个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
10

如果=有时表示赋值,有时表示比较,这样不同的上下文使用会令人困惑,容易出错,显然不是个好主意。

此外,现有语法与C和C ++兼容,许多人都熟悉它。

是否有任何理由在if语句中为变量分配一个新值(如果有,请提供示例)?

while循环中这是相当常见的情况:

int b;
while ((b=in.read()) != -1){

你能在if语句中声明一个变量吗? - java
1
有趣的事实:VB(和VB.NET)对赋值和相等性都重载了=。[VB] a = b = c == [Java] a = b == c;(不是[Java] a = b = c;)。 - michaelb958--GoFundMonica
@michaelb958:但是他们根本没有==,对吧?所以这也是一致的。 - Thilo

3
= 

被用于赋值。

== 

用于比较。

在if语句中赋值给变量(或初始化新变量)是否允许?

是允许的。


不允许初始化新变量,如果我没记错的话。这只允许在 for 中使用。 - nhahtdh
不允许初始化。 但可以进行赋值。 - eyadMhanna

1

在if语句中给变量赋值或初始化新变量是否被允许?

是的。通常用于此目的的习惯用法为:

String line = null;
while ( (line = in.readLine()) != null ) {
  // do work
}
在循环中,line被赋值并与null进行比较。我想不出一个整数的例子;在那里肯定不清楚。

在if语句中使用and?我无法将一个变量设置为另一个变量或int类型的变量,否则会出现某种错误。 - java
@java:你不能简单地设置变量。如果你想设置一堆变量,那么你可以在 while 循环之前这样做。除非你可以将赋值嵌入到比较中,就像示例中一样,否则你将无法在 while 的条件中进行赋值。也就是说,如果这样写不自然和令人困惑,不要强迫自己这样写。 - nhahtdh
1
所以你想让 = 在条件语句和语句中表现不同,而且在 whileif 的条件中也表现不同? - Thilo

1
请注意,当您使用if (x = 3.141)时会得到什么错误消息; 这是一种类型错误(无法从double转换为boolean)。 赋值的类型是其两边的类型; 如果赋值的类型是布尔型(if (x = true)或甚至if (x = a.equals(b))), 那么这样写是合法的。 因此,既然在条件语句中将值分配给布尔值是合法的,那么您必须使用==进行比较。

如果赋值的类型是布尔型(if (x = true)),那么写成这样是合法的。虽然如此,但这很可能是一个错误。为什么要赋值后立即测试呢? - nhahtdh
1
@nhahtdh 改变了我的例子。虽然我同意这是糟糕的风格。 - zw324

1

编程语言的历史101:

  • Fortran使用=进行赋值和比较。
  • Algol引入了:=用于赋值,并使用=进行比较。这是为了解决语法二义性而必需的。
  • Pascal效仿Algol。
  • PL/1则未采用Algol的做法。
  • 我不能代表B或BCPL,但当我们使用C时,赋值使用=,比较使用==,同样是为了解决语法二义性问题。
  • C++在C的基础上发展而来。
  • Java在很多方面跟随C++的做法,包括此处。

语法二义性的问题在于允许表达式中出现赋值语句。与您的说法相反,如果x是布尔类型,if (x = true)在Java中是合法的。


1

== 是一个身份比较器,可以同时用于对象和基本数据类型。它回答了这个问题:“这两个东西是不是同一个东西”。

= 是一个赋值操作符。它将左侧的值设置为右侧的值。

当在布尔值上使用示例时,可能会出现错误:

boolean b;

if (b = true) // This compiles, but is a bug, because it sets b, not tests it

尽管其他类型无法使用此语法进行编译,但booleanBoolean可以,因此建议使用以下模式:

if (b)

0

所以..

= 是赋值运算符,== 是比较运算符,并且无论在哪里使用,它们的作用始终如此。

而“声明”不同于赋值。赋值语句有其返回值,而声明没有。因此,您不能在 if 语句的 () 中写入 boolean a = false,但是在已经声明了变量 a 之后,您可以写入 a = false

并非所有的赋值都是合法的。例如:

int index;
if (index = str.indexOf("something")) {
    ...
}

这是不合法的,因为String.indexOf(String)返回一个整数,而if需要一个布尔值。

此外,“合法”和“有意义”之间存在巨大的差异。

int index;
if ((index = str.indexOf("something")) != -1) {
    ...
}

这是合法的,因为!=操作返回一个布尔值,并且这是有意义的,因为我确实想检查字符串是否包含子字符串“something”;

然而,

int index;
boolean flag;
if ( flag = ((index = str.indexOf("something")) != -1) ) {
    ...
}

这也是合法的,因为最后的语句返回一个布尔值;但这没有意义,因为!=语句已经返回了一个布尔值。


你不能在条件语句中使用声明的原因是语法不允许,而不是因为“声明没有返回值”。 - user207421

0

在 if 语句中,你绝对可以给一个变量赋值。而且,这就是它的工作方式:= 总是表示赋值,== 总是表示比较。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,