有嵌套赋值和普通赋值之间有什么区别吗?

huangapple go评论71阅读模式
英文:

Is there any difference between nested assignment and normal assignment?

问题

我有一段代码:

final int a, b;
a = b = 10;

while (a <= b) {
    System.out.println("this is in while loop");
}
System.out.println("this is out of while loop");

在这种情况下,我的while循环会无限执行。

我有另一段代码:

final int a = 10;
final int b = 10;

while (a <= b) {
    System.out.println("this is in while loop");
}
System.out.println("this is out of while loop");

在这种情况下,我得到了编译错误,指出while循环外的语句是不可达的。

尽管它们是final变量,我尝试在两种情况下重新分配变量a和b的值,但我不能在这两种情况下重新分配值,因为它是final变量。但在我提到的第一种情况中,它们不被视为常量,这就是循环重复的原因。

英文:

I have a code

final int a, b;
a = b = 10;

while (a &lt;= b) {
	System.out.println(&quot;this is in while loop&quot;);
}
System.out.println(&quot;this is out of while loop&quot;);

in this case my while block is executing infinite times.

In have another code

final int a=10;
final int b = 10;

while (a &lt;= b) {
	System.out.println(&quot;this is in while loop&quot;);
}
System.out.println(&quot;this is out of while loop&quot;);

in this case i am getting compilation error mentioning unreachable code for the statement outside while loop

even though they are final variables.I tried to reassign the values for variables a and b respectively in both cases,But i could not re -assign the values in both cases as it is final variable.
but in the first case i mentioned they are not considering as constants that is the reason loop is repeating.

答案1

得分: 1

以下是翻译好的内容:

在这两种情况下,变量都是final,但第二种情况中的变量也是常量变量

常量变量是使用常量表达式(§15.29)初始化的原始类型或String类型的final变量。变量是否是常量变量可能会涉及到[...]可达性(§14.22)[...]等方面的影响。

第一种情况中的变量不是常量变量,因为它们没有初始化。它们在下一条语句中被赋值。请注意,final变量不必初始化,它们只需要是明确赋值的

这使得第二个代码中的a <= b成为一个常量表达式,其常量值为true。这会影响语句是否可达。请参阅本节中的相关引用。

如果语句因为无法执行而无法执行,这是一个编译时错误。

在非空块中的第一条不是switch块的语句是可达的,如果该块是可达的。

在非空块中的每个其他语句S,如果S之前的语句可以正常完成,那么S是可达的。

  • 如果以下至少一个条件为真,则while语句可以正常完成:

    • while语句是可达的,且条件表达式不是具有值true的常量表达式(§15.29)。

    • 存在可达的break语句退出while语句。

在这种情况下,由于while语句具有常量true条件,并且没有break语句,因此while语句无法正常完成。这导致while循环后的语句无法达到。

英文:

While in both cases the variables are final, the variables in the second case are also constant variables:

> A constant variable is a final variable of primitive type or type String that is initialized with a constant expression (§15.29). Whether a variable is a constant variable or not may have implications with respect to [...] reachability (§14.22) [...].

The variables in the first case are not constant variables, because they are not initialised. They are assigned in the next statement. Note that final variables don't have to be initialised = they just need to be definitely assigned.

This makes a &lt;= b in the second code a constant expression, with the constant value true. And this affects whether a statement is reachable. See the relevant quotes in this section.

> It is a compile-time error if a statement cannot be executed because
> it is unreachable.
>
> The first statement in a non-empty block that is not a switch block is reachable iff the block is reachable.
>
> Every other statement S in a non-empty block that is not a switch
> block is reachable iff the statement preceding S can complete
> normally.
>
> - A while statement can complete normally iff at least one of the following is true:
>
> - The while statement is reachable and the condition expression is not a constant expression (§15.29) with value true.
>
> - There is a reachable break statement that exits the while statement.

In this case, since the while statement does have a constant true condition, and there is no breaks, the while statement cannot complete normally. This causes the statement after the while loop to be unreachable.

答案2

得分: 0

I explain this phenomenon in an unprofessional way, the test class is as follows:

package com;

public class Assignment {
    public static void main(String[] args) { }
    public int m1() {
        final int a, b;
        a = b = 10;
        return a + b;
    }
    public int m2() {
        int a, b;
        a = b = 10;
        return a + b;
    }
    public int m3() {
        final int a = 10;
        final int b = 10;
        return a + b;
    }
}

After compiling with javac, the result of decompiling with javap is as follows:

Compiled from "Assignment.java"
public class com.Assignment {
  public com.Assignment();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: return

  public int m1();
    Code:
       0: bipush        10
       2: dup
       3: istore_2
       4: istore_1
       5: iload_1
       6: iload_2
       7: iadd
       8: ireturn

  public int m2();
    Code:
       0: bipush        10
       2: dup
       3: istore_2
       4: istore_1
       5: iload_1
       6: iload_2
       7: iadd
       8: ireturn

  public int m3();
    Code:
       0: bipush        20
       2: ireturn
}

Pay attention to m3, the value of return is directly replaced with 20!

Both m1 and m2 are calculated, that is, the specific values ​​are not known until the running phase.

So...., the next conclusion can be drawn,The value in m3 can actually be determined during the compilation phase. If you put it in while as a condition, then you can know the result during the compilation phase.

英文:

I explain this phenomenon in an unprofessional way, the test class is as follows:

package com;                                                                                                       
                                                                                                                   
public class Assignment {                                                                                          
    public static void main(String[] args) { }                                                                           
    public int m1() {                                                           
        final int a, b;                                                         
        a = b = 10;                                                             
        return a + b;                                                                                              
    }                                                                           
    public int m2() {                                                           
        int a, b;                                                               
        a = b = 10;                                                             
        return a + b;                                                                                              
    }                                                                                                              
    public int m3() {                                                           
        final int a = 10;                                                                                          
        final int b = 10;                                                       
        return a + b;                                                           
    }                                                                           
}

After compiling with javac, the result of decompiling with javap is as follows:

Compiled from &quot;Assignment.java&quot;
public class com.Assignment {
  public com.Assignment();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object.&quot;&lt;init&gt;&quot;:()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: return

  public int m1();
    Code:
       0: bipush        10
       2: dup
       3: istore_2
       4: istore_1
       5: iload_1
       6: iload_2
       7: iadd
       8: ireturn

  public int m2();
    Code:
       0: bipush        10
       2: dup
       3: istore_2
       4: istore_1
       5: iload_1
       6: iload_2
       7: iadd
       8: ireturn

  public int m3();
    Code:
       0: bipush        20
       2: ireturn
}

Pay attention to m3, the value of return is directly replaced with 20!

Both m1 and m2 are calculated, that is, the specific values ​​are not known until the running phase.

So...., the next conclusion can be drawn,The value in m3 can actually be determined during the compilation phase. If you put it in while as a condition, then you can know the result during the compilation phase.

huangapple
  • 本文由 发表于 2023年5月11日 13:59:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76224542.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定