Как работает switch case java
Перейти к содержимому

Как работает switch case java

  • автор:

Как работает switch case java

The switch statement is a multi-way branch statement. In simple words, the Java switch statement executes one statement from multiple conditions. It is like an if-else-if ladder statement. It provides an easy way to dispatch execution to different parts of code based on the value of the expression. Basically, the expression can be a byte, short, char, or int primitive data types. It basically tests the equality of variables against multiple values.

Note: Java switch expression must be of byte, short, int, long(with its Wrapper type), enums and string. Beginning with JDK7, it also works with enumerated types (Enums in java), the String class, and Wrapper classes.

Some Important Rules for Switch Statements

  1. There can be any number of cases just imposing condition check but remember duplicate case/s values are not allowed.
  2. The value for a case must be of the same data type as the variable in the switch.
  3. The value for a case must be constant or literal. Variables are not allowed.
  4. The break statement is used inside the switch to terminate a statement sequence.
  5. The break statement is optional. If omitted, execution will continue on into the next case.
  6. The default statement is optional and can appear anywhere inside the switch block. In case, if it is not at the end, then a break statement must be kept after the default statement to omit the execution of the next case statement.

Flow Diagram of Switch-Case Statement

Syntax: Switch-case

Note: Java switch statement is a fall through statement that means it executes all statements if break keyword is not used, so it is highly essential to use break keyword inside each case.

Example: Consider the following java program, it declares an int named day whose value represents a day(1-7). The code displays the name of the day, based on the value of the day, using the switch statement.

How To Use switch In Modern Java

Since Java 14 introduced switch expressions, using switch isn’t as straight-forward as it used to be: colons or arrows, statement or expression, labels or patterns? Here’s how to best use switch in modern Java.

A fancy gear switch from some modern car

How To Use switch In Modern Java

Share this post with your community:

I'm active on various platforms. Watch this space or follow me there to get notified when I publish new content:

Share this post with your community:

I'm active on various platforms. Watch this space or follow me there to get notified when I publish new content:

When it comes to using switch past Java 14, there are three decisions to be made:

  • colons ("classic") or arrows (since Java 14)
  • statement ("classic") or expression (since Java 14)
  • labels ("classic") or patterns (3rd preview in Java 19)

This leaves us with a whopping eight possible combinations! Fortunately for us, these three decisions are completely orthogonal (meaning neither impacts any other), so we can examine each in isolation. So let's do that and find out how to best use switch in modern Java!

If you're looking for one particular decision, note that there's a table of contents that lets you skip ahead in the box on the left.

▚Colon vs Arrow

▚Colon and break

The "classic" version uses a colon after the case label (or pattern) and requires a return or break to prevent falling through into the next case:

Preventing all fall-through with break s is the common case, but there are situations where it is intended. Fall-through is often used to list several cases with empty branches, so they fall through into the one with statements (and usually a break ), thus applying the same behavior to all cases:

Non-trivial fall-through from a branch with statements into one with even more is sometimes the best solution but it's also easy to get wrong, miss, or misunderstand. Having the less common case opt-out (not opt-in) makes it error prone to the point where linters usually issue a warning on non-trivial fall-through (i.e. after a non-empty branch) and some action (like adding a comment) is required to silence it. Then, the common case is verbose because of the break and the rare case even more so because of the comment.

In my opinion, fall-through is one of those cases where Java's default didn't stand the test of time.

▚Arrow

Since Java 14, switch allows using the lambda arrow to "map" from case to code:

It doesn't fall through — not only not by default but not at all, which is superb. And it comes with two bonuses:

It's common to write lambdas on a single line and so it's common to have case and branch on a single line, too. (Nothing stopped us from doing the same in the colon form, of course, we just usually didn't.)

To have multiple statements in a branch, you need to create a block with < >, which immediately gives you a new scope for local variables, so you can easily reuse variable names in different branches.

(Again, we could've done the same with colons, but we rarely did.)

▚Colon vs Arrow

To me, this decision is super easy: Arrow form all day, every day.

That is, unless I can't avoid fall-through, which I try because it's harder to understand. Fortunately, the ability to list multiple case labels (see below) eliminates a big use case for it.

That leaves non-trivial fall-through as the only reason I see to use the "classic" form and I hope that spotting colons in switch will become a strong indicator that there's fall-through ahead, which would alert us to pay extra attention to this more complicated construct.

From here on out, I'll only use arrows but all examples also work with : and break .

▚Statement vs Expression

▚Switch Statement

This is the "classic" form: The value of the switch variable determines the branch, which then gets executed. The end.

▚Switch Expression

Using switch as an expression works the same way, but the story doesn't end after the execution. Instead, the switch as a whole takes on the value of the computation, which can then be assigned to a variable (or passed as an argument, but that's horribly unreadable):

▚Exhaustiveness

By definition, an expression has a value and so a switch expression must always compute to one. Consequently there must be a branch for each possible value of the switch variable — this is called exhaustiveness.

In the example above, without the default branch, string would be undefined if number were neither 1 nor 2 , which would make the switch non-exhaustive. The compiler catches that and throws an error.

But exhaustiveness checks don't end there! While a default branch will always make a switch exhaustive, it isn't required — if the cases cover all possible values, e.g. of an enum, that suffices:

Without a default branch, new Count values (say THREE is added), lead to compile errors, which will make us consider how to handle that new case. With a default branch, on the other hand, new cases are (silently) caught and processed by it. Java's switch allows us to pick the behavior that best fits each given situation.

(NB: Check the section on patterns for more on exhaustiveness.)

▚Statement vs Expression

Some problems can only be solved reasonably with a switch statement. For example, when each case requires calling different methods that have no return values (or they're not needed):

For other problems, switch expressions are clearly the better fit. For example, when a value needs to be "translated" to a different value:

But there'll be a lot of cases, where it's not clear cut and both approaches work reasonably well. This will often be the case when a value needs to be translated and then passed to a method (or methods) that's the same in each branch:

This is probably a matter of personal taste, but I lean towards using expressions in these scenarios for a few minor reasons. In order or decreasing importance:

  • the expression is checked for exhaustiveness
  • the "translate, then call" logic is more directly mirrored on the code, making it a bit easier to spot
  • it introduces an additional variable that I can give a name (hopefully a better one than string ��), which helps readability

Regarding exhaustiveness, I tend to avoid default branches whenever possible, preferring to get compile errors when things change.

My recommendation when getting to know switch expressions is to frequently implement both variants (it usually only takes a few minutes) and compare them side by side to figure out which one works better in that scenario and why. Such comparisons make great topics for pair programming, code reviews, at the water cooler, and every other bikeshed-adjacent location. In my experience, intuition for what to do when builds after a few weeks of consistent use and reflection.

▚Labels vs Patterns

▚Labels

Not much to say about classic case labels except that you can now have many of them after one case :

Super handy to replace trivial fall-through.

▚Patterns

The details of pattern matching in switch are still in flux (there'll be a third preview in Java 19), so this section is somewhat speculative, but there are three aspects that are particularly interesting for this conversation.

▚Exhaustiveness

Earlier, I motivated the need for switch expressions to be exhaustive with the fact that an expression has to have a value. But while classic switch statements don't have to be exhaustive, it's surely helpful if they are because then new cases don't accidentally result in no behavior. And "all switches must be exhaustive" is a simpler model than "all switch expressions must be exhaustive".

To be able to get there in the future, it's helpful not to take one more step into the wrong direction in the present and so pattern switches will likely have to be exhaustive — even if used in a statement. That would leave us with "all switches must be exhaustive, except statements with labels" — not very intuitive, but hopefully temporary.

▚Type Patterns

At the time of writing, Java only supports type patterns, with deconstruction patterns for records proposed by JEP 405. They can already be used in if -statements but soon also in switch , which begs the question when to use what.

I think the switch comes out ahead:

  • it more clearly expresses the intend to execute exactly one branch based on obj 's properties
  • the compiler checks exhaustiveness
  • if a value needs to be computed (not the case here), use as an expression is more succinct

This is a categorically new aspect in our deliberations. So far we've discussed what kind of switch to use in "switchy" situations but haven't considered that more situations may become "switchy" — this scenario changes that. It suggests that there are situations where switch can (should?) replace if — else — if chains. Let's see another, less immediate example.

▚When Clauses

When clauses (formerly guarded patterns) refine a pattern with additional boolean checks. While this is currently not being proposed, there has been talk on the mailing list (couldn't find the link ��) about one day allowing conditions without the preceding pattern. It could work like this (syntax made up by me):

Again, this could be an if — else — if chain instead, but again I think the switch comes out ahead (for the same reasons as above).

With switch becoming more powerful, my guess is that it will start to eat into the use cases for longer if — else — if chains. And it makes sense because that's the core tenet of switch :

Here's a bunch of possibilities for this value — pick one and compute.

It communicates that much more clearly than an if — else — if chain and so I hope to some day see it being used in all such situations.

▚Labels vs Patterns

After that excursion into switch vs if , let's get back to when to use what form of switch . Now: labels vs patterns. The answer to that is super simple, though, as it is fully determined by what you want to check for the switch variable.

Need to compare to specific values? Use labels.

Need to check structural properties? Use patterns.

▚Reflection

How to best use switch :

Colons or arrows: Always arrows (to avoid dealing with fall-through), except when non-trivial fall-through is needed. Statement or expression: Often dictated by the problem, but where both work, lean towards expression (to benefit from exhaustiveness checks and to make code clearer by surfacing the logical flow). Initially, consider implementing both variants to build an understanding of the trade-offs. Labels or patterns: Dictated by the problem, but keep in mind that patterns (particularly "pure" when clauses if they ever come) may make switch preferable to if .

Java Switch Statement

Java switch statements help in providing multiple possible execution paths for a program. Java switch statements can be used in place of if-else statements to write more cleaner and concise code.

Java switch statements have evolved over time. In this tutorial, we will learn about basic switch statement features and new features in later versions of Java.

1. Switch Statements

1.1. Syntax

The general form of a switch statement is –

The expression value must be one of the following 6 types:

    e.g. byte , short , char , and int e.g. Character , Byte , Short , and Integer (added in Java 5) (added in Java 7)

Here labelOne, labelTwo and labelThree are “compile-time constant expressions” or constants (the value of the labels must be known at compile-time).

We can achieve similar functionality with a chain of if-else blocks, but the switch statement is more readable and clean.

1.2. Execution Flow

A switch statement is evaluated as follows:

  1. First of all, the switch expression is evaluated.
  2. The datatype of the expression value and case labels must be same.
  3. Second, the value of expression is matched against the value of each case label. If the value of the expression matches a case label, the execution starts from the matched case label and executes all statements until the break statement is encountered.
  4. If the value of the expression does not match any case label, execution starts at the statement following the optional default label and continues until the end of the switch statement or the break statement is encountered.

We can easily guess that the use of a break statement inside the default label is not necessary because the default label is the last label in the switch statement and the execution of the switch statement will stop after that anyway.

1.3. Demo

In this example, we are checking if today is a weekend or weekday, using the switch statement. For storing all the days in a week, we have created an enum.

Notice how we have created a total of eight case labels that return an appropriate true or false value.

The above example works as expected, but we can make it better. As we see that multiple case labels are returning the same value, so we can group the case labels to make the code more readable.

There is still a chance of improvement. In the above example, having the break statements does not look good. We can remove the break statements using the new arrow syntax. It is available since Java 13.

2. Switch Expressions

Java 12 introduced the switch expressions which can compute the value for the whole switch statement and assign its value to a variable. It is very similar to other normal Java statements.

2.1. Return value with Arrow Syntax

Let us rewrite the last example, with a switch expression. Notice line no. 11 where we are directly assigning the value of the switch statement to the variable result.

2.2. Return Value with yield Keyword

In the above example, we are writing only the return value in the case statements. What if we have to execute multiple statements before returning any value from a given case block.

In such cases, yield keyword helps in returning a computed value from a multi-statement block.

In the given example, we have written only a print statement. You can write as many statements as needed.

3. Switch Examples

3.1. Better instanceof checking with Switch Statements

Traditionally, if we had to write a code that checks the instance type and perform some logic, it was the way:

In Java 17, we can rewrite the whole expression in the following manner;

3.2. Handling null Values

Traditional switch statements throw NullPointerException if the selector expression evaluates to null .

From Java 17, we can check for null values as the separate case itself.

4. Restrictions

4.1. Case Label Values Must be in Range of DataType

Please note that the value of the constant expressions used as the case labels must be in the range of the data type of switch expression.

The range of the byte data type in Java is -128 to 127, so the following code would not compile because the second case label is 150, which is outside the range of the byte data type:

4.2. Duplicate Case Labels are Not Allowed

Another important point to note is that two case labels in a switch statement cannot be the same. The following piece of code would not compile because case label 10 is repeated:

Java Switch Statement

Navigating the complexities of Spring can be difficult, even for seasoned developers.

If you need direct, practical help and guidance with your own Spring work, Trifork’s CTO, Joris Kuipers, is running a closed-door call.

It’s free, but it’s limited to only 3 seats, so if you need it, I would join quickly and be sure to attend:

With more than 15 years of leading custom software development projects involving Spring, Joris has gained a lot of real-world experience, and this call is about sharing and helping the community.

Building or modernizing a Java enterprise web app has always been a long process, historically. Not even remotely quick.

That’s the main goal of Jmix is to make the process quick without losing flexibility — with the open-source RAD platform enabling fast development of business applications.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Simply put, a single Java or Kotlin developer can now quickly implement an entire modular feature, from DB schema, data model, fine-grained access control, business logic, BPM, all the way to the UI.

Jmix supports both developer experiences – visual tools and coding, and a host of super useful plugins as well:

Slow MySQL query performance is all too common. Of course it is. A good way to go is, naturally, a dedicated profiler that actually understands the ins and outs of MySQL.

The Jet Profiler was built for MySQL only, so it can do things like real-time query performance, focus on most used tables or most frequent queries, quickly identify performance issues and basically help you optimize your queries.

Critically, it has very minimal impact on your server’s performance, with most of the profiling work done separately — so it needs no server changes, agents or separate services.

Basically, you install the desktop application, connect to your MySQL server, hit the record button, and you’ll have results within minutes:

The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.

To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.

Connect your cluster and start monitoring your K8s costs right away:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *