Java 爪哇语:在一个开关盒中,不能在一个盒后断开-为什么?
我编了一个游戏。 我使用SwitchCase实现了一个状态机。 问题是,如果是ZIEHEN_SP,break语句就不起作用。 当我调试它时,编译器只需跳过break语句,然后转到下一个例子ZIEHEN_BA 我对编译器忽略break语句的部分进行了注释 为什么?Java 爪哇语:在一个开关盒中,不能在一个盒后断开-为什么?,java,switch-statement,Java,Switch Statement,我编了一个游戏。 我使用SwitchCase实现了一个状态机。 问题是,如果是ZIEHEN_SP,break语句就不起作用。 当我调试它时,编译器只需跳过break语句,然后转到下一个例子ZIEHEN_BA 我对编译器忽略break语句的部分进行了注释 为什么? import java.util.*; 导入java.util.Scanner; 导入java.io.*; 黑杰克2级{ 静态整数芯片=100; 静态int einsatz=0; 枚举状态{INIT,EINSATZ,ZIEHEN_SP,
import java.util.*;
导入java.util.Scanner;
导入java.io.*;
黑杰克2级{
静态整数芯片=100;
静态int einsatz=0;
枚举状态{INIT,EINSATZ,ZIEHEN_SP,ZIEHEN_BA}
静态状态=State.INIT;
静态ArrayList bankKarten=新ArrayList();
静态ArrayList SpilerKarten=新ArrayList();
静态扫描仪=新扫描仪(System.in);
静态字符串s=“”;
静态int eingabe=0;
静态void init(){
System.out.println(“\nEin neues Spiel beginnt:”);
bankKarten.clear();
斯皮尔卡顿;
bankKarten.add(giveCard());
添加(giveCard());
}
静态空隙切屑塞森(){
einsatz=0;
如果(芯片==0){
System.out.print(“\nSie haben”+chips+“chips!”);
系统出口(1);
}
做{
系统输出打印(“\nSie haben”+芯片+芯片”);
System.out.print(“\n您是否已设置?”;
试一试{
einsatz=Integer.parseInt(scanner.next());
}捕获(例外e){
}
}while(einsatz芯片);
芯片-=einsatz;
}
静态int sumSpielerKarten(){
整数和=0;
对于(int i=0;i 21 | |(s>b&s 21 | | b>s | | b==21&&s!=21){
ret=“银行”;
}else如果(b==s){
ret=“两者”;
}
返回ret;
}
静态int updateMoney(int s,int b){
字符串获胜者=评估获胜者(s,b);
int newChips=0;
如果(获胜者=“玩家”){
新芯片=einsatz*2+芯片;
}否则如果(获胜者=“双方”){
新芯片=einsatz+芯片;
}否则如果(获胜者=“银行”){
新芯片=芯片;
}
System.out.println(“获胜者:+Winner”);
归还新芯片;
}
静态无效显示卡(){
系统输出打印(“\n银行:\t”);
对于(int i=0;i,因为您将state
更改为与state.ZIEHEN_BA
条件匹配的值:
state = State.ZIEHEN_BA;
因此,这里:
while(true){
...
state = State.ZIEHEN_BA;
break;
case ZIEHEN_BA:
banksTurn();
state = State.INIT;
break;
...
}
在循环的下一次迭代中执行案例ZIEHEN_BA
Eclipse显示的可能是在运行时或由编译器执行的JVM优化
编辑
我已经完成了测试,我不认为这是编译器优化。
请看这个最小的示例,在这种情况下,我没有设置状态:
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
break;
case B:
break;
}
}
}
}
下面是main()方法的反汇编代码:
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 39
default: 39
}
36: goto 4
39: goto 4
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 43
default: 43
}
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
40: goto 4
43: goto 4
看看我在案例A中设置的状态在案例B中输入的版本:
public class TestSwitch {
public enum MyEnum {
A, B
};
public static void main(String[] args) {
MyEnum state = MyEnum.A;
while (true) {
switch (state) {
case A:
state = MyEnum.B;
break;
case B:
break;
}
}
}
}
下面是main()方法的反汇编代码:
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 39
default: 39
}
36: goto 4
39: goto 4
public static void main(java.lang.String[]);
Code:
0: getstatic #18 // Field a/TestSwitch$MyEnum.A:La/TestSwitch$MyEnum;
3: astore_1
4: invokestatic #24 // Method $SWITCH_TABLE$a$TestSwitch$MyEnum:()[I
7: aload_1
8: invokevirtual #27 // Method a/TestSwitch$MyEnum.ordinal:()I
11: iaload
12: tableswitch { // 1 to 2
1: 36
2: 43
default: 43
}
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
40: goto 4
43: goto 4
此编译代码中没有优化。
案件A执行后:
36: getstatic #31 // Field a/TestSwitch$MyEnum.B:La/TestSwitch$MyEnum;
39: astore_1
下一条指令是转到循环:
40: goto 4
因此,优化可能是由JVM或Eclipse调试器在运行时执行的。编译器优化了您的代码:-)
当您将开关变量设置为State.ZIEHEN_BA
时,在这两行之间没有要执行的内容(while(true)
和重新输入开关),这正是下一行要执行的内容
我不确定它是否应该以这种方式运行(在开关内部打开变量将导致检查以下情况),但在您的情况下,我完全同意编译器
正如您在本例中所看到的,这种行为并不总是如此:
public static void main(String[] args) {
int i = 3;
switch(i) {
case 1:
System.out.println("1:");
break;
case 2:
System.out.println("2:");
break;
case 3:
System.out.println("3:");
i = 5;
break;
case 4:
System.out.println("4:");
break;
case 5:
System.out.println("5:");
i = 5;
break;
case 6:
System.out.println("6:");
break;
case 7:
System.out.println("7:");
break;
default:
break;
}
System.out.println("I = " + i);
}
导致
3:
I = 5
这是一个优化。当您将状态设置为ZIEHEN_BA时,编译器知道它将作为下一步到达那里。如果没有优化,只会有一些传统的步骤,但无论如何它都会到达那里:
设置状态;执行中断;转到while(true),现在执行切换并…它到达ZIEHEN_BA。因此,这相当于直接到达那里。实际上,编译器并没有忽略中断
当您在现有案例语句中设置state=state.ZIEHEN_BA
时
因此,在调用break之后,它将在while(ture)
循环的下一次迭代中直接进入ZIEHEN_BA
。)
通过忽略break
,它似乎会直接进入ZIEHEN_BA
,但它会在接下来的迭代中进入那里。您编写的主程序是一个不可中断的循环。一旦我们正确地看到代码,您就会在遇到某个情况时将状态分配给另一个情况。而且,您永远不会结束中断了循环。while循环不知道在哪里停止。不确定你想做什么
仅供参考,中断没有被跳过,但它只起到了中断开关循环的作用。我猜您的期望是中断while循环…
如果希望代码在特定点停止,请在while循环中放置一个中断。再次在开关中放置break;
不会起作用,因为它会中断开关循环。相反,请尝试在while之前设置一个布尔变量
,并在希望循环中断的位置将变量值更改为false
。o使用C?将状态设置为状态。ZIEHEN_BA
并在开关
周围有一个循环,那么除了进入该状态之外,你还期望什么呢?在开关
求值中更改状态
的值是个坏主意。在开关
中,你应该将下一个状态分配给一个新变量在开关
语句中断后,再次循环,并且自状态更改后,调试