java 如何证明'&&'和'||'的优先级 通过在java中编码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4436669/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:21:15  来源:igfitidea点击:

How to PROVE the precedence of '&&' and '||' by CODING in java?

javaoperator-precedence

提问by pf_miles

I knew from somewhere that logical and: '&&' has a higher precedence than logical or: '||' in java.And while programming I rarely make mistakes on them. But till now I didn't find any clue about how this precedence really act? What would happen if I didn't know about the precedence of the two and what mistake would I make? I tried to write some code to PROVE the precedence of '&&' and '||' but failed, for example:

我从某处知道逻辑和:'&&' 的优先级高于逻辑或:'||' 在 java.And 编程时,我很少在它们上犯错误。但直到现在我还没有找到任何关于这种优先级究竟是如何起作用的线索?如果我不知道两者的优先级会发生什么,我会犯什么错误?我试图写一些代码来证明 '&&' 和 '||' 的优先级 但失败了,例如:

boolExp1 || boolExp2 && boolExp3 || boolExp4

the code above would produce same results no matter the precedence of '&&' and '||', that is , 'false || false && true || false' results false no matter what the precedence are.

无论 '&&' 和 '||' 的优先级如何,上面的代码都会产生相同的结果,即 'false ||' 假 && 真 || 无论优先级如何,false' 的结果都是错误的。

So, in other words, I want a method or function, that could PROVE the precedence of '&&' and '||', it should produce different results depends on the precedence of '&&' and '||'... How could this function being made?Is it possible? I guess it maybe a tough question or a dramatically simple one...may be it's not a java problem but something math... All in all, somebody help? Thanks.

所以,换句话说,我想要一个方法或函数,可以证明 '&&' 和 '||' 的优先级,它应该产生不同的结果取决于 '&&' 和 '||' 的优先级......如何这个功能可以做吗?可以吗?我想这可能是一个棘手的问题,也可能是一个非常简单的问题……可能不是 Java 问题而是数学问题……总而言之,有人帮忙吗?谢谢。

回答by Jon Skeet

Let's take your example expression:

让我们以您的示例表达式为例:

boolExp1 || boolExp2 && boolExp3 || boolExp4

Now we believe that acts as:

现在我们相信它的作用是:

boolExp1 || (boolExp2 && boolExp3) || boolExp4

right?

对?

So let's suppose the oppositeis true, and it's actually

所以让我们假设相反的情况是正确的,实际上是

(boolExp1 || boolExp2) && (boolExp3 || boolExp4)

What values of boolExp1etc would give us different results?

boolExp1etc 的哪些值会给我们带来不同的结果?

Well, let's take:

好吧,让我们来看看:

boolExp1 = true
boolExp2 = false
boolExp3 = false
boolExp4 = false

Under the "&& has higher precedence" rules, the result would be true. Under the "|| has higher precedence rules", the result would be false. A quick test shows that the expression evaluates to true, however.

在“&& 具有更高优先级”规则下,结果将为真。在“|| 具有更高优先级规则”下,结果将是错误的。然而,快速测试表明该表达式的计算结果为真。

Of course, this doesn't actually prove that && has higher precedence than || - merely that || doesn't have higher precedence than &&. We could consider whether they have equalprecedence - and test that with other expressions in a similar way... find a sample expression and values which would give different results under different precedence rules, and test them.

当然,这实际上并不能证明 && 的优先级高于 || - 只是|| 没有比 && 更高的优先级。我们可以考虑它们是否具有相同的优先级 - 并以类似的方式用其他表达式测试它......找到一个示例表达式和值,在不同的优先级规则下会给出不同的结果,并测试它们。

Ultimately though, I prefer:

但最终,我更喜欢:

  • To trust the spec unless I have specific doubts
  • To use parentheses to make my intentions clear
  • 相信规范,除非我有特别的疑虑
  • 用括号来表达我的意图

I wouldn't use the first expression "as is" in the first place... because unless you actually knowthe precedence rules (and I suspect many Java devs don't - I couldn't swear that I'd have got && and || right) you're in the dark. Better to make it explicit and clear where there's any doubt.

我不会首先使用“原样”的第一个表达式......因为除非你真的知道优先规则(我怀疑许多 Java 开发人员不知道 - 我不能发誓我会得到 &&和 || 对)你在黑暗中。最好在有任何疑问的地方说清楚。

回答by janos

If &&didn't have higher precedence than ||, then this expression:

如果&&没有比 更高的优先级||,则此表达式:

a || b && c

would be evaluated like this:

会这样评价:

(a || b) && c

To verify if this is the case or not, you can generate all combinations of a, b, and c, and compare the result of these two expressions, to see if they are always equal or not, that is:

要验证是否是这种情况,您可以生成ab、 和 的所有组合c,并比较这两个表达式的结果,看它们是否始终相等,即:

  1. For all combinations of a, b, and c
  2. Verify that: (a || b && c) == ((a || b) && c)
  1. 对于所有组合abc
  2. 验证: (a || b && c) == ((a || b) && c)

Sample code:

示例代码:

for (int i = 0; i < 8; ++i) {
    boolean a = ((i >> 2) & 1) == 1;
    boolean b = ((i >> 1) & 1) == 1;
    boolean c = (i & 1) == 1;
    boolean x1 = (a || b && c);
    boolean x2 = ((a || b) && c);

    if (x1 != x2) {
        System.out.println(String.format("%s %s %s", a, b, c));
        System.out.println(String.format("   %s || %s  && %s => %s", a, b, c, x1));
        System.out.println(String.format("  (%s || %s) && %s => %s", a, b, c, x2));
    }
}

The output:

输出:

true false false
   true || false  && false => true
  (true || false) && false => false
true true false
   true || true  && false => true
  (true || true) && false => false
true false false
   true || false  && false => true
  (true || false) && false => false
true true false
   true || true  && false => true
  (true || true) && false => false

As such, &&has higher precedence than ||.

因此,&&具有比 更高的优先级||

回答by WorkMindDesigns

I too had this same question but the answer was practically giving to me. Here is my example:

我也有同样的问题,但答案实际上是给我的。这是我的例子:

true || true && false

is equivalent to

相当于

true || (true && false)

So with this example it is easy to see that under the hood in Java the logical && has a higher precedence than ||.

所以在这个例子中很容易看出,在 Java 中,逻辑 && 比 || 具有更高的优先级。

回答by Dan D.

I was looking at the java specification to see if they defined operator precedence for &&and ||

我正在查看 java 规范,看看他们是否为&&and定义了运算符优先级||

Both are defined as left-associative and no operator precedence is defined.

两者都被定义为左关联并且没有定义运算符优先级。

See s. 15.7.3 a bit down from s. 17.7, &&s. 15.23, ||s. 15.24

s。15.7.3 比 s 低一点。17.7&&秒。15.23||秒。15.24

i.e. Java defines:

即Java定义:

boolExp1 || boolExp2 && boolExp3 || boolExp4

As:

作为:

((((boolExp1) || boolExp2) && boolExp3) || boolExp4)

回答by Stephen C

You cannot prove anything useful about a programming language by just writing / running examples. For all you know, the compiler might be implemented so as to compile code in an illogical, inconsistent or non-deterministic fashion.

您不能仅通过编写/运行示例来证明有关编程语言的任何有用信息。就您所知,编译器可能被实现为以不合逻辑、不一致或不确定的方式编译代码。

Even if you assume deterministic compilation and deterministic execution, the only thing that compiling / running an example proves is that that particular exampleexhibits a particular behavior. You cannot logically generalize from one example to another one, because without reference to a specification the compiler is just a black box. (Your very next example could be the one that is handled in a totally counter-intuitive fashion.)

即使您假设确定性编译和确定性执行,编译/运行示例的唯一证明是该特定示例表现出特定行为。你不能从一个例子逻辑地概括到另一个例子,因为如果不参考规范,编译器只是一个黑匣子。(您的下一个示例可能是以完全违反直觉的方式处理的示例。)

The correct way to develop an understanding of a programming language is to read the language specification, a good textbook or a good tutorial. Combine this with writing code to confirm your understanding.

培养对编程语言的理解的正确方法是阅读语言规范、一本好的教科书或一本好的教程。将此与编写代码结合起来以确认您的理解。

If you rely solelyon reading example code and writing test programs, you are liable to pick up misconceptions, and bad habits that can be painful to unlearn.

如果你仅仅依赖于阅读示例代码和编写测试程序,你很可能会养成一些误解和坏习惯,而这些习惯会让你很难忘记。

回答by 8bittree

A simple test is:

一个简单的测试是:

boolean a = true || false && false;
boolean b = false && false || true;

if (a == b) { // different precedence
    if (a == true) {
        System.out.println("&& has higher precedence than ||");
    } else { // a == false
        System.out.println("|| has higher precedence than &&");
    }
} else { // a != b, same precedence
    if (a == true) { // and b == false
        System.out.println("&& and || have equal precedence, and are executed right to left.");
    } else { // a == false, b == true
        System.out.println("&& and || have equal precedence, and are executed left to right.");
    }
}

Note that this accounts for the possibility that &&and ||could have equal precedence, and then, in that case, determines if they're executed left to right, or right to left.

请注意,这说明了&&||可能具有相同优先级的可能性,然后在这种情况下确定它们是从左到右还是从右到左执行。

Unfortunately, this does not account for precedence that changes or precedence based on inside to outside or outside to inside, or many other possible orders of operation, not to mention it can be defeated by malicious or broken compilers, malicious or broken computers, and cosmic rays.

不幸的是,这并没有考虑到基于从内到外或从外到内的更改或优先级,或许多其他可能的操作顺序,更不用说它可以被恶意或损坏的编译器、恶意或损坏的计算机以及宇宙射线。

Anyway, it's really hard to prove your compiler/computer/universe isn't messing with you. So check the language specification in addition to testing.

无论如何,真的很难证明你的编译器/计算机/宇宙没有惹你。所以除了测试,还要检查语言规范。

回答by Peter Lawrey

This is relyed upon all the time in lines like the following.

这始终依赖于如下所示的行。

Clearly these examples would blow up if the first expression were not always evaluated and the second expression not evaluated conditionally.

很明显,如果第一个表达式不总是被求值并且第二个表达式不是有条件地求值,那么这些例子就会失败。

// second expression on evaluated if text != null in both cases.
String text = ??
if (text != null && text.length() > 0) 

if (text == null || text.length() == 0

回答by Amrut Prabhu

Both && and || have the same precedence, Evaluation happens from left to right. Let me explain with an example.

&& 和 || 具有相同的优先级,评估从左到右进行。让我用一个例子来解释。

public static void main(String[] args) {

    System.out.println("Result = " + (arg1() || arg2() && arg3() || arg4()));
}

private static boolean arg1() {
    System.out.println("arg1");
    return false;
}

private static boolean arg2() {
    System.out.println("arg2");
    return true;
}

private static boolean arg3() {
    System.out.println("arg3");
    return true;
}

private static boolean arg4() {
    System.out.println("arg4");
    return false;
}

this evaluates to :-

这评估为:-

arg1
arg2
arg3
Result = true

But now let me change arg3() to return false

但是现在让我更改 arg3() 以返回 false

private static boolean arg3() {
    System.out.println("arg3");
    return false;
}

this results in :-

这导致:-

arg1
arg2
arg3
arg4
Result = false

So to conclude.. the evaluation takes place form left to right i.e

所以总而言之..评估从左到右进行,即

arg1 || arg2 && arg3 || arg4
   output    && arg3 || arg4
           output    || arg4
                   output 

Hope this helps.

希望这可以帮助。