Win a copy of Serverless Applications with Node.js this week in the NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Junilu Lacar
  • Paul Clapham
  • Knute Snortum
Saloon Keepers:
  • Stephan van Hulst
  • Ron McLeod
  • Tim Moores
  • salvin francis
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Vijitha Kumara

What do you think about the use of the default statement in the switch?  RSS feed

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm developing an app where I'm using a switch to handle events (it's a menu).

Now there is a debate in the office about use or not to use the default, because it is a switch.

I think that this is not like a mathematical function and not need an otherwise case, then I do not need put the default in the switch, like I not need put else in all my if.

What do you think about this, if you know all cases for the switch, you would put the default or not?

Thanks for the answers
 
Saloon Keeper
Posts: 10002
208
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's a good idea to add a default case, yes. The reason is that in a future iteration of your application, someone might add a new enum constant without checking all places where the enum is used. You want to make sure you have some sort of default handling for enums that you don't expect to see at that point in time.
 
Marshal
Posts: 63853
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Let's ask you a question. If your options run 1...7, what are you going to do it you get 0 or 8?Now, add a default to that. What are you going to do? Print a message, reassign a boolean, throw an exception? Maybe an exception is overkill, but without some other action, your user won't know to enter a new option.That shows that default: is useful for handling incorrect input, and I think you are probably better off with a default:My boolean has to be reassigned 7×
But now try to add an option for input = 8. You have two places at least where you have to change 7 to 8.Yes, it would look a lot better if I hadn't used magic numbers 1 2 3 4 5 6 7. Yes, it would look better if your getInput() method loops until the input is in the requisite range, in which case my do loop probably becomes unnecessary, and there is less need for the default:
But apart from that, I think a default: is useeful, and I think this discussion shows how awkward a switch‑case can be to maintain. Of course, you would usually only need a switch‑case for a console application run from the terminal/command line.
 
Rancher
Posts: 3991
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:My boolean has to be reassigned 7×



You could assign needsInput as false initially (at the top of the loop), then only set it to true in the default.
In other words, assume the input is OK and only change the flag if it isn't.
That reduces your reassignment to once.
 
Campbell Ritchie
Marshal
Posts: 63853
209
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Damn! DT has seen through my evil scheme caught me making a mistake
 
Stephan van Hulst
Saloon Keeper
Posts: 10002
208
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Most of my switch statements look roughly like this:
 
Dave Tolls
Rancher
Posts: 3991
47
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Damn! DT has seen through my evil scheme caught me making a mistake



That's what code reviews are for!
 
Jose Fa
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Welcome to the Ranch

Let's ask you a question. If your options run 1...7, what are you going to do it you get 0 or 8?Now, add a default to that. What are you going to do? Print a message, reassign a boolean, throw an exception? Maybe an exception is overkill, but without some other action, your user won't know to enter a new option.[code=java]do
{
  int input = getInput(1, 7);
  switch (input)
  {
     case 1:
...



But in this case you have a random input in this example you have otherwise input, but in a code that is under control, this not happen, for example sitch for a enum, and the precondition is that you always get this value of enum.
I think that this example is different from the one.
Thanks for your answer!
 
Jose Fa
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:Most of my switch statements look roughly like this:



I like this aproach, then you think that even if you have absolute control of data entry by preconditioning, it should be a correct option to set default?
 
Campbell Ritchie
Marshal
Posts: 63853
209
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Jose Fa wrote:. . . for example sitch for a enum, and the precondition is that you always get this value of enum. . . .

Agree; if you are using enum elements as constants for the different cases, and you use every enum element as a label to acase, you will never reach default. But I can envisage two situations where that approach will fail:-
  • 1: Your user passes null.
  • 2: Somebody enhances the enum by adding another element.
  •  
    Jose Fa
    Greenhorn
    Posts: 4
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:

    Jose Fa wrote:. . . for example sitch for a enum, and the precondition is that you always get this value of enum. . . .

    Agree; if you are using enum elements as constants for the different cases, and you use every enum element as a label to acase, you will never reach default. But I can envisage two situations where that approach will fail:-
  • 1: Your user passes null.
  • 2: Somebody enhances the enum by adding another element.


  • Agree the first case can happen, but the second case really is that a human mistake, the develop forgot put the new values to the Switch, but do you think that those errors should be foreseen with code? there are many types of human errors, and in the development we work with preconditions, postconditions etc, because if we do not check everything everywhere, what do you think about this?
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It is easy enough to enforce a precondition that the argument isn't null. But programmers, like other people, do daft things; it is quite conceivable that somebody would alter a class like that and “break” other code. That is when you would want error messages or an exception.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 10002
    208
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Nulls should be checked for and guarded against with an IllegalArgumentException.

    You can write a simple unit test that makes sure that a method is familiar with all declared enum constants, even those that were added later:


    The test makeFlavor_withAnyColor_returnsSomething will fail if we extend the Color enum with BLUE and don't add a case to makeFlavor().
     
    Bartender
    Posts: 20580
    121
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:It is easy enough to enforce a precondition that the argument isn't null. But programmers, like other people, do daft things; it is quite conceivable that somebody would alter a class like that and “break” other code. That is when you would want error messages or an exception.



    This is known as "anti-bugging". Making allowances for things that are "never supposed to happen". By employing anti-bugging techniques in your code, you can detect, these "impossible" things, report them, and (hopefully) make some sort of sane recovery from them.

    The other use for a "default" in a switch statement is when you have lots of potential case values, but even more values which all fall under a general case. A good example might be if you're processing a Unicode String (not that Java has any other kind!) that's full of Arabic text, and you want to convert the "arabic" digits in it (which are actually Hindu-Arabic) to standard ASCII-style "Western" digits (which are actually Arabic*). You could have a switch statement for the arabic digits that returned their western counterparts, and the default, which returns any other character unchanged. That is, you'd have specific cases to handle Unicode values '\u06F0'..'\u06F9' and translate them to '0'..'9', but everything else comes out unchanged.

    That's actually a practical application, incidentally. Modern-day practice is often to use Western digits even in languages that historically had digit symbols of their own, especially Arabic, Chinese and other East-Asian languages, so a switch like this could facilitate normilisation of foreign-language text.

    ----
    * One of history's little jokes.
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tim Holloway wrote:. . . . Making allowances for things that are "never supposed to happen". . . . anti-bugging . . . detect[s] these "impossible" things . . .

    Not come across that particular term, but it simply puts a name to something I already know. It sound like a type of defensive programming.
    My first supervisor has this touching belief that programmers are sensible people who would never provide something of the wrong type or value and he was surprised that I was so much more suspicious than him. Of course you don't have to amke such istakes intentionally; a mere slip of the finger onto the wrong key will do.
    It may be some time before you discover somebody has added something to yoru enum, but anti‑bugging/defensive programming will prevent it from doing any harm.

    "Western" digits (which are actually Arabic*). . . .
    * One of history's little jokes.

    So‑called because they were invented in India?
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Stephan van Hulst wrote:. . .

    Why throw that exception? Wouldn't illegal argument exception be appropriate?
     
    Tim Holloway
    Bartender
    Posts: 20580
    121
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    https://en.wiktionary.org/wiki/antibugging

    According to Merriam-Webster, the term was first used in 1957, although in my case, I ran across it in the 1980s, probably in a book by Henry F. Ledgard (Programming Proverbs) or something by Andrew Tannenbaum.

    The C assert mechanism was designed as an anti-bugging assist. Ironically, Java's assertion mechanism is something I've almost never used. It's overly complicated and I usually use either selectable log levels or ordinary program code instead. The C assert stuff was done in macros, so when you compiled with assertions off, less code/runtime CPU and memory overhead, back when such things were major concerns. Plus, the optimization abilities of compilers is a lot stronger these days, I've also been known to do "if ( true ) ..." constructs for debugging that can be changed to "if ( false ) ..." when development is done, secure in the knowledge that "if ( false ) " won't generate code and the compiler can be convinced not to whine about it, producing spurious compilation messages.

    I had extremely strong reasons for being heavy into anti-bugging back in the early '80's. I was working in the OS support group on a large IBM mainframe, which means that failing software could literally shut down the entire company. And we were expected to be so diligent that we never wore pagers (which, alas, was not true for the applications group). But when something did go down, the late-night operators could be so maddeningly cheerful as they dragged you out of bed and down to work at 2 AM.

    In later years, I could at least dial in, but since the IBM manuals were all dead trees in a 10-foot long rack at the office, there was a strong incentive to make the failing code as informative as possible. Plus, being awakened in the wee hours is annoying, commute or no commute.
     
    Tim Holloway
    Bartender
    Posts: 20580
    121
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    It was a joke about the numerals when I took Arabic at Uni. Originally, the Greeks simply used letters of the Greek alphabet to represent numbers. The Romans, of course, used Roman Numerals. But Roman Numerals are cumbersome and they don't allow for zeros. The Arabs, however, had invented a true decimal digit notation, complete with zero, digit-positions and special numeric characters, which were essentially what we use today. IIRC, it leaked over from Al-Andalus (Spain) into Italy, somewhere around the 1300s and eventually took over Europe.

    But India had also developed one or two similar notations, and while I'm unclear, I think that in more Eastern- (India-)facing parts of the Arab world, they adopted that notation instead. Both systems are used identically, only the shapes of the digits differ. If you're really imaginative, you can more or less correlate the value of a digit character by the number of "kinks" in the Hindu-Arabic characters up to a point* - they're more angular than Western Arabic characters.

    If your browser is agreeable, I've pasted them below:

    . ۱ ۲ ۳ ٤
    ٥
    ٦ ۷ ۸ ۹

    Sorry about the confused layout. It kept trying to force right-to-left ordering on some of the digits. Which is ironic. Arabic writing is right-to-left, but numbers in Arabic are written left-to-right, just like we do.
    ====
    * And just to make the jest even better, the Indo-Arabic zero is exactly that - a point (dot). Not to be confused with a decimal point. Although I see that the sample I copied used a circle
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Tim Holloway wrote:. . . the number of "kinks" in the Hindu-Arabic characters . . .

    I remember that from “Mathematical Pi” when I was about twelve. In those days, zero was a circle: no kinks or corners.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 10002
    208
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:Why throw that exception? Wouldn't illegal argument exception be appropriate?


    Not necessarily. If I write my method contract in such a way that it promises to have a valid code path for every available constant of the enum, then it is not a mistake on part of the caller of the code, and IllegalArgumentException would be inappropriate.

    For instance, the makeFlavor() method could promise to come up with a Flavor for every Color known. If I add the constant BLUE to the Color enum and release the code without updating makeFlavor(), a client of my library might run into problems and wonder what happened. If they got an IllegalArgumentException, they will shake their fists and silently curse us for not having BLUEBERRY flavor. If they get AssertionError they might be more willing to let us know our assertion that we know about every Color is wrong.
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah! Thank you
     
    Campbell Ritchie
    Marshal
    Posts: 63853
    209
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    This morning, I wrote:. . .

  • 2: Somebody enhances the enum by adding another element.
  • This post of Rob Spoor's suggests a possible solution in the near future.
     
    Tim Holloway
    Bartender
    Posts: 20580
    121
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Just in case anyone's confused, the circle in my Hindu-Arabic sample is the number 5. As I said, it got into fights when I tried to paste it. The original copy/paste was using a circle for zero and something like a circle with a dent in the bottom for 5, but that was the original source getting confused with Urdu numbering or something like that.
     
    Sheriff
    Posts: 13393
    221
    Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    At the risk of totally derailing the conversation, I have long gone away from switch-case statements to handle menu options. For one, that kind of code violates OCP (Open-Closed Principle) -- every time you want to modify the menu, you have to modify the Menu class. It's way too easy for someone to screw up the logic.

    Whenever I have an app that gets extended multiple times with new menu options, I start refactoring the Menu and routing logic so that I can simply create a new MenuOption subclass, then add an instance of it to a list of MenuOption objects that I will then inject into the Menu object that I have configured as a component in my Dependency Injection framework, usually Spring.

    The next time I have to add a menu option, I just write the test to verify the routing logic, implement the MenuOption handler, make sure an instance gets added to the list of menu options, rebuild the project, then redeploy. You might even be able to make it so that MenuOption objects are deployed in a separate jar file that can be hot-deployed so you won't even need to restart your main app. I don't know, but I seem to remember similar things being done with other third party libraries and plug-ins. Maybe modules in the newer versions of Java allow you to do that kind of thing as well, I don't know. If that's possible, I'd definitely consider that option. It would be so easy peasy.

    I'm such a lazy programmer.
     
    Tim Holloway
    Bartender
    Posts: 20580
    121
    Android Eclipse IDE Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hardly off-topic. The question was specifically in regards to menus and whether switch/case is a good option.

    Menus in full-on GUI systems like Swing are generally not dealt with as switch/case, but instead are linked to some sort of action object and fired directly from the GUI menu manager as event calls. There are all sorts of reasons for this, from the fact that often the user is given the ability to customise menus, meaning that entries can be added/removed/re-ordered, making an absolute index questionable, to the fact that often menu actions can be fired by non-menu resources such as function keys, hotkeys, toolbar buttons, pop-up context menus, and so forth.

    The most likely case you're going to see a strict numbered-item menu is in a purely command-line based program, where you don't have all those extra features. In which case, I'd normally expect the menu dispatched to be a single class, and any submenus likewise, and the maintenance is going to be fairly straightforward, since the head, if not the entirety of the menu action code is going to be the predicate clause of the specific value case. And while a switch cannot detect when you've removed an element, you will get a compile error if you attempt to use the same value more that once as a switch value.

    Note that a text menu app is entirely different. If your menu expects you to type in specific multi-character commands, then the question is more complex. I'd probably keep a map from the command words to an enum and use a switch, but it depends on how complex the command options are. And whether the commands have to be internationalized.
     
    Brace yourself while corporate america tries to sell us its things. Some day they will chill and use tiny ads.
    global solutions you can do at home or in your backyard
    https://www.kickstarter.com/projects/paulwheaton/better-world-boo
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!