为什么变量在 case 语句中不是局部的?

2022-09-05 00:37:09

我最近向一个Android Java应用程序添加了另一个菜单项,并且惊讶地发现Eclipse说上一个案例中的变量:break不是本地的(所以我只是添加了一个后缀来获取)。

我有点困惑,因为在我的脑海中,如果选择了第二个选项,第1组情况:break根本不会被执行。有人可以解释我错误的想法吗?

        case R.id.menuDebugMode:
            debugMode = !debugMode;
            if (debugMode){
                Toast.makeText(mainActivity.this, "Debug Mode on - NOT TO BE USED WHILST DRIVING", Toast.LENGTH_LONG).show();           
            } else {
                tvDebug.setText("");
                tvInfo.setText("");
            }
            SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
            SharedPreferences.Editor editor = settings.edit();
            editor.putBoolean("debugMode", debugMode);
            editor.commit();
        break;

        case R.id.menuSpeedMode:
            speedSignMode = !speedSignMode;
            if (speedSignMode){
                Toast.makeText(mainActivity.this, "SpeedSign Mode in use", Toast.LENGTH_LONG).show();           

            } else {
                    Toast.makeText(mainActivity.this, "MapSpeed Mode in use", Toast.LENGTH_LONG).show();            
            }
            SharedPreferences settings2 = getSharedPreferences(PREFS_NAME, 0);
            SharedPreferences.Editor editor2 = settings2.edit();
            editor2.putBoolean("speedSignMode", speedSignMode);
            editor2.commit();
        break;`

答案 1

你是对的,最多一个会执行,但一个案例不会创建一个新的范围。您可以手动创建具有自己作用域的块。

case foo:
    {
       int var = ...
    }
    break;

case bar:
    {
       int var = ...
    }
    break;

答案 2

与C一样,在Java中,switch语句不是人们在查看它时所期望的。缩进使得很难理解未创建作用域。这一切都归结为C,其中开关只是句法糖。编译器将开关转换为多个条件跳转。这使得该语言能够使用fall-through,这是在C设计期间打算使用的功能(“break”仍然是可选的)。这个Java功能仍然与C兼容。

switch(a):
    case 1:
        dosomething();
    case 2:
        dosomemore();

被翻译成

if(a==1) jump ##1;
if(a==2) jump ##2;
jump ##3;
##1:
dosometing();
##2:
dosomemore();
##3:

推荐