java 引用悬挂,Java语句,处理优先级(“悬挂”)

给出以下有效的代码:

Boolean a = false;

if (a)

System.out.println("A");

else

System.out.println("!A");

根据文档,if(包括其条件和内部statement)也是statement。例如:

if (b){

System.out.println("B");

}

是statement。

但是,当我们要用另一个替换现有的语句时,它不应该触及整体逻辑,对吗?假设我们将(Expression)-statement替换为上面的if-statement:

Boolean a = false;

Boolean b = false:

if (a)

if (b){

System.out.println("A and B");

}

else

System.out.println("!A");

Java编译器将按以下方式解释代码示例(完整的大括号以进行说明):

Boolean a = false;

Boolean b = false:

if (a){

if (b){

System.out.println("A and B");

} else {

System.out.println("!A");

}

}

这不是最初的逻辑。

那么,为什么将一个语句与另一个语句交换会改变逻辑呢?

从示例中可以清楚地看出,问题仅在于括号,但是如果省略括号,我将找不到有关java确切处理该方式的信息。

关于这种行为有什么记载吗?为什么Java倾向于将else连接到更新的if,而不是解析时遇到的第一个if?

如果将else连接到第一个if,如果它下面还有另一个,该怎么办?

您从ORACLE引用的语句可能仅在使用花括号时适用。

这是模棱两可的常见领域。 维基百科悬空其他文章。 您说"这不是最初的逻辑"。 在您的问题中,但事实是,根据Java编译器,这是初始逻辑。 如果Java像Python一样,它关心缩进,那么它就能够按照您的预期进行区分,因为else与第一个if处于同一级别,但是强制缩进实际上与强制缩进相同。 使用花括号。

如果您真的想对Java有所了解,那么Java Specification是一个有价值的工具。 第2节将对您和您的问题感兴趣。

@ Marco13,您应该发布相关的此文本和链接作为答案。

当然,答案在Java语言规范中。相关部分是第14.5节"声明",它准确地描述了这种情况:

As in C and C++, the if statement of the Java programming language suffers from the so-called"dangling else problem," illustrated by this misleadingly formatted example:

if (door.isOpen())

if (resident.isVisible())

resident.greet("Hello!");

else door.bell.ring();  // A"dangling else"

The problem is that both the outer if statement and the inner if statement might conceivably own the else clause. In this example, one might surmise that the programmer intended the else clause to belong to the outer if statement.

最后:

The Java programming language, like C and C++ and many programming languages before them, arbitrarily decrees that an else clause belongs to the innermost if to which it might possibly belong.

(我强调) sub>

谢谢你的回答。 我认为在看完整的示例时这是很明显的,但是采用带有语句思想的replace语句并不是编译器的工作-因为它是ofc。 不关心else的优先分配。 (好吧,这就是为什么我总是使用大括号,由于一些快速代码的延迟而刚遇到这个问题)

通过将其与最新的if关联,您知道您只需要阅读最新的if即可理解其逻辑。否则,您将阅读所有if和所有else子句以了解它们中的任何一个。

假设您没有最近执行过操作,但是最近执行过if。

if (a)

if (b)

something();

else // if this is else to if (a)

something();

else if (c) // what is this the else to?

something();

else

something();

当您有多个else子句时,如果else用于最新的if,则更容易阅读

没错(并记录在JLS中,请参阅@ Marco13的答案)

Java程序的DOM(称为AST,抽象语法树)是一种更为纯净的结构,通常用作基础来讨论代码的含义,语义。

线性文本具有许多分析缺点,例如:

-(-y) equal to y for most int values

--y

悬空的else是一点。

在计算机科学中,有时仅在符号级别上处理声明性语言(函数,逻辑)。另一方面,C / C ++众所周知是上下文相关的。

这是正确的行为。如果在if语句之后没有大括号,则仅将第一条语句视为真实条件的一部分。您的示例的问题是没有大括号来定义语句的范围条件评估之后紧接着有一个花括号。

在第一个if语句之后,第二个if语句使用花括号并建立语句的优先级。您应使用如下代码:

Boolean a = false;

Boolean b = false:

if (a){

if (b)

System.out.println("A and B");

}

else

System.out.println("!A");

它按预期工作,您的缩进没有任何意义。 else是指与if(b)有关的最近值

您应该使用以下代码:

Boolean a = false;

Boolean b = false:

if (a)

if (b){

System.out.println("A and B");

} else

System.out.println("!A");

但是总的来说,使用大括号{}始终是一个好习惯

问题是关于文档

Java是一种面向对象的语言,从本质上讲意味着它在编译代码时遵循自下而上的方法。

这就是为什么它将最新的if语句视为else部分的伴侣。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值