Java 为什么我们需要在案件陈述后休息?

Java 为什么我们需要在案件陈述后休息?,java,switch-statement,case,language-design,break,Java,Switch Statement,Case,Language Design,Break,为什么编译器不在开关中的每个代码块之后自动放置break语句?是历史原因吗?您希望何时执行多个代码块?编译器没有添加自动中断,因此可以使用开关/案例来测试类似1的条件。有时,将多个案例与同一代码块关联会很有帮助,例如 case 'A': case 'B': case 'C': doSomething(); break; case 'D': case 'E': doSomethingElse(); break; 等等,只是一个例子 根据我的经验,通常“失败”并在

为什么编译器不在开关中的每个代码块之后自动放置break语句?是历史原因吗?您希望何时执行多个代码块?

编译器没有添加自动中断,因此可以使用开关/案例来测试类似
1的条件。有时,将多个案例与同一代码块关联会很有帮助,例如

case 'A':
case 'B':
case 'C':
    doSomething();
    break;

case 'D':
case 'E':
    doSomethingElse();
    break;
等等,只是一个例子


根据我的经验,通常“失败”并在一个案例中执行多个代码块是一种不好的风格,但在某些情况下可能会用到它。

因此,如果需要多个案例来执行相同的操作,则不必重复代码:

case THIS:
case THAT:
{
    code;
    break;
}
或者你可以做如下事情:

case THIS:
{
   do this;
}
case THAT:
{
   do that;
}
以级联方式


如果你问我的话,真的很容易出现错误/混乱。

没错,因为通过一些巧妙的布局,你可以在级联中执行块。

你可以用case fall-through做各种有趣的事情

例如,假设您希望对所有情况执行特定操作,但在特定情况下,您希望执行该操作加上其他操作。使用带有fall-through的switch语句将使它变得非常简单

switch (someValue)
{
    case extendedActionValue:
        // do extended action here, falls through to normal action
    case normalActionValue:
    case otherNormalActionValue:
        // do normal action here
        break;
}

当然,很容易忘记案例末尾的
break
语句,从而导致意外行为。当您省略break语句时,好的编译器会发出警告

因为在某些情况下,您希望流经第一个块,例如,以避免在多个块中写入相同的代码,但仍然能够将它们分割以进行mroe控制。还有很多其他原因。

Java来自C,这就是C的语法

有时您希望多个case语句只有一个执行路径。 下面的示例将告诉您一个月有多少天

class SwitchDemo2 {
    public static void main(String[] args) {

        int month = 2;
        int year = 2000;
        int numDays = 0;

        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                numDays = 31;
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                numDays = 30;
                break;
            case 2:
                if ( ((year % 4 == 0) && !(year % 100 == 0))
                     || (year % 400 == 0) )
                    numDays = 29;
                else
                    numDays = 28;
                break;
            default:
                System.out.println("Invalid month.");
                break;
        }
        System.out.println("Number of Days = " + numDays);
    }
}

我认为这是一个错误。作为一种语言结构,使用
break
和默认值一样简单,而是使用
fallthrough
关键字。我写过和读过的大多数代码在每种情况下都会有一段中断。

Java源于C,它的传统包括一种称为C的技术。 这是一种优化,它依赖于这样一个事实:在没有
中断的情况下,控制从一个案例下降到下一个案例语句。当C语言被标准化时,有大量类似于“在野外”的代码,如果改变语言来打破这种结构,将会适得其反

为什么编译器不在开关中的每个代码块之后自动放置break语句

撇开良好的愿望不谈,希望能够在几个情况下使用相同的块(可能是特殊情况)

是历史原因吗?您希望何时执行多个代码块

它主要是为了与C兼容,可以说是一个古老的黑客,从
goto
关键字漫游地球的时代就开始了。当然,它确实实现了一些令人惊奇的事情,例如,但不管这是对它有利还是反对的观点,充其量都是有争议的。

,这是因为
案例
本质上定义了一个
标签
,也称为
转到
调用。switch语句及其关联的case实际上只是表示一个多路分支,在代码流中有多个潜在的入口点


尽管如此,人们已经注意到,
break
几乎总是每个案例结束时的默认行为。

根据历史记录,Tony Hoare在20世纪60年代“结构化编程”革命期间发明了案例陈述。Tony的case语句支持每个case使用多个标签,并且自动退出,而不会发出臭味
break
语句。明确的
中断
要求来自BCPL/B/C行。丹尼斯·里奇(在ACM HOPL-II中)写道:

例如,语言中不存在从BCPL switchon语句转义的endcase 当我们在20世纪60年代了解到它时,因此重载break关键字来转义 从B和C转换的说法来看,这是发散的进化,而不是有意识的变化


我还没有找到任何关于BCPL的历史著作,但里奇的评论表明,
中断
或多或少是一个历史性的意外。BCPL后来解决了这个问题,但也许Ritchie和Thompson太忙于发明Unix而不关心这样一个细节:-)

这是一个老问题,但事实上,我今天无意中使用了case with break语句。当您需要按顺序组合不同的函数时,不使用break实际上非常有用

e、 g.使用http响应代码使用时间令牌对用户进行身份验证

服务器响应代码401-令牌过期->重新生成令牌并登录用户。
服务器响应代码200-令牌正常->用户登录

在案例陈述中:

case 404:
case 500:
        {
            Log.v("Server responses","Unable to respond due to server error");
            break;
        }
        case 401:
        {
             //regenerate token
        }
        case 200:
        {
            // log in user
            break;
        }

使用此功能,您无需为401响应调用登录用户函数,因为当重新生成令牌时,运行时跳转到案例200。

您可以轻松地分离其他类型的数字、月份、计数。
如果在这种情况下,这会更好

public static void spanishNumbers(String span){

    span = span.toLowerCase().replace(" ", "");
    switch (span){
     case "1":    
     case "jan":  System.out.println("uno"); break;    
     case "2":      
     case "feb":  System.out.println("dos"); break;    
     case "3":     
     case "mar":  System.out.println("tres"); break;   
     case "4":   
     case "apr":  System.out.println("cuatro"); break;
     case "5":    
     case "may":  System.out.println("cinco"); break;
     case "6":     
     case "jun":  System.out.println("seis"); break;
     case "7":    
     case "jul":  System.out.println("seite"); break;
     case "8":    
     case "aug":  System.out.println("ocho"); break;
     case "9":   
     case "sep":  System.out.println("nueve"); break;
     case "10":    
     case "oct": System.out.println("diez"); break;
     }
 }

我现在正在做一个项目,我需要在我的switch语句中使用
break
,否则代码将无法工作。请耐心听我说,我会给你一个很好的例子,说明为什么在switch语句中需要
break

假设您有三种状态,一种等待用户输入数字,第二种等待用户计算数字,第三种等待用户打印总和

在这种情况下,您有:

  • 状态1-等待用户输入数字
  • 状态2-打印总和
  • 状态3-计算总和
  • 看看这些州,你会希望精确的顺序从st开始
    public static void spanishNumbers(String span){
    
        span = span.toLowerCase().replace(" ", "");
        switch (span){
         case "1":    
         case "jan":  System.out.println("uno"); break;    
         case "2":      
         case "feb":  System.out.println("dos"); break;    
         case "3":     
         case "mar":  System.out.println("tres"); break;   
         case "4":   
         case "apr":  System.out.println("cuatro"); break;
         case "5":    
         case "may":  System.out.println("cinco"); break;
         case "6":     
         case "jun":  System.out.println("seis"); break;
         case "7":    
         case "jul":  System.out.println("seite"); break;
         case "8":    
         case "aug":  System.out.println("ocho"); break;
         case "9":   
         case "sep":  System.out.println("nueve"); break;
         case "10":    
         case "oct": System.out.println("diez"); break;
         }
     }
    
    while(1){
        switch(state){
          case state1:
            // Wait for user input code
            state = state3; // Jump to state3
            break;
          case state2:
            //Print the sum code
            state = state3; // Jump to state3;
          case state3:
            // Calculate the sum code
            state = wait; // Jump to state1
            break;
        }
    }
    
    public class SwitchTester{
        private static final Log log = LogFactory.getLog(SwitchTester.class);
        public static void main(String[] args){
            log.info(monthsOfTheSeason(Season.WINTER));
            log.info(monthsOfTheSeason(Season.SPRING));
            log.info(monthsOfTheSeason(Season.SUMMER));
            log.info(monthsOfTheSeason(Season.AUTUMN));
        }
    
        enum Season{WINTER, SPRING, SUMMER, AUTUMN};
    
        static String monthsOfTheSeason(Season season){
            switch(season){
                case WINTER:
                    return "Dec, Jan, Feb";
                case SPRING:
                    return "Mar, Apr, May";
                case SUMMER:
                    return "Jun, Jul, Aug";
                case AUTUMN:
                    return "Sep, Oct, Nov";
                default:
                    //actually a NullPointerException will be thrown before reaching this
                    throw new IllegalArgumentException("Season must not be null");
            }        
        }
    }   
    
    12:37:25.760 [main] INFO lang.SwitchTester - Dec, Jan, Feb
    12:37:25.762 [main] INFO lang.SwitchTester - Mar, Apr, May
    12:37:25.762 [main] INFO lang.SwitchTester - Jun, Jul, Aug
    12:37:25.762 [main] INFO lang.SwitchTester - Sep, Oct, Nov
    
    public class SwitchExpressionsNoFallThrough {
    
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            int value = scanner.nextInt();
            /*
             * Before JEP-325
             */
            switch (value) {
                case 1:
                    System.out.println("one");
                case 2:
                    System.out.println("two");
                default:
                    System.out.println("many");
            }
    
            /*
             * After JEP-325
             */
            switch (value) {
                case 1 ->System.out.println("one");
                case 2 ->System.out.println("two");
                default ->System.out.println("many");
            }
        }
    }
    
    //input
    1
    // output from the implementation before JEP-325
    one
    two
    many
    // output from the implementation after JEP-325
    one
    
    //input
    2
    // output from the implementation before JEP-325
    two
    many
    // output from the implementation after JEP-325
    two
    
    // input
    3
    many // default case match
    many // branches to 'default' as well