Όπως μια εντολή if/else, έτσι και μια εντολή switch σου επιτρέπει να αλλάξεις τη ροή του προγράμματος εκτελώντας κώδικα υπό συνθήκη.
Η διαφορά είναι ότι μια εντολή switch μπορεί να συγκρίνει την τιμή μιας έκφρασης πρωτογενούς τύπου ή συμβολοσειράς μόνο με προκαθορισμένες σταθερές τιμές.
Κάποιες λέξεις-κλειδιά είναι χρήσιμες όταν χρησιμοποιείς μια εντολή switch.
switch: αυτή η λέξη-κλειδί σου επιτρέπει να δηλώσεις τη δομή του switch.
Ακολουθείται από την έκφραση ή τη μεταβλητή που θα καθορίσει το αποτέλεσμα.case: αυτή θα τη χρησιμοποιήσεις για να δηλώσεις τις διαφορετικές περιπτώσεις του αποτελέσματος.break: η λέξη-κλειδί break είναι πολύ χρήσιμη για να σταματήσεις την εκτέλεση του switch στο τέλος της ροής που θέλεις.
Αν την ξεχάσεις, το πρόγραμμα θα συνεχίσει και μπορεί να οδηγήσει σε απρόσμενα αποτελέσματα.default: όπως λέει και το όνομά της, χρησιμοποίησέ την ως προεπιλεγμένο αποτέλεσμα όταν καμία άλλη περίπτωση δεν ταιριάζει με το αποτέλεσμα της έκφρασής σου.Στην απλούστερη μορφή τους ελέγχουν μια έκφραση πρωτογενούς τύπου ή συμβολοσειράς και παίρνουν μια απόφαση με βάση την τιμή της. Για παράδειγμα:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
Ξεκινώντας από τη Java 14 (διαθέσιμη ως preview νωρίτερα στη Java 12 και 13) είναι δυνατό να χρησιμοποιήσεις την "ενισχυμένη" υλοποίηση του switch.
Έχεις τη δυνατότητα να αντιστοιχίσεις πολλές τιμές σε ένα μόνο case.
Στην παραδοσιακή εντολή switch μπορείς να χρησιμοποιήσεις το fall-through. Στο παρακάτω παράδειγμα τα case 1 και case 3 θα εκτελέσουν τα ίδια πράγματα.
Αυτό συμβαίνει επειδή το case 1 δεν χρησιμοποιεί τη λέξη-κλειδί break.
switch (number) {
case 1:
case 3:
// do same stuff
break;
case 2:
// do different stuff
break;
// (...)
}
Στην ενισχυμένη switch expression μπορείς να αντιστοιχίσεις απευθείας πολλές τιμές σε ένα case.
Δες το παρακάτω παράδειγμα:
switch (number) {
case 1, 3:
// do stuff
break;
case 2:
// do other stuff
break;
// (...)
}
Μπορείς τώρα να γράψεις ένα switch-statement ή μια switch expression.
Ποια είναι η διαφορά;
Βασικά, μια εντολή απαιτεί κάποια αυστηρή λογική, ενώ μια έκφραση μπορεί να επιστρέψει μια τιμή.
Αντί για:
String result = "";
switch (expression) {
case "bob":
result = "bob";
break;
// (...)
}
Μπορείς να κάνεις:
String result = switch (expression) {
case "bob":
yield "bob";
// (...)
}
Το yield λειτουργεί σαν return, με τη διαφορά ότι προορίζεται για την έκφραση switch.
Επειδή το yield τερματίζει την έκφραση, το break δε χρειάζεται εδώ.
Μια άλλη διαφορά ανάμεσα στις εντολές switch και στις εκφράσεις switch: στις εκφράσεις switch ΠΡΕΠΕΙ να καλύψεις όλες τις περιπτώσεις.
Είτε έχοντας ένα case για όλες τις πιθανές τιμές είτε χρησιμοποιώντας μια περίπτωση default.
Μπορείς να χρησιμοποιήσεις το -> αντί για το :.
Το -> σου επιτρέπει να μη συμπεριλάβεις τη λέξη-κλειδί break.
Μπορείς να χρησιμοποιήσεις και τους δύο συμβολισμούς, αλλά σε ένα switch πρέπει να μείνεις σε έναν μόνο.
switch(expression) {
case 1 -> yield "one"
case 2 -> yield "two"
default: yield "other number" // Removing this will result in a compile error
}
Η εμβέλεια.
Το παραδοσιακό switch μπορεί να οδηγήσει σε απρόσμενη συμπεριφορά εξαιτίας της εμβέλειάς του, καθώς υπάρχει μόνο μία εμβέλεια για ολόκληρο το switch.
switch(expression) {
case 1:
String message = "something";
break;
case 2:
String message = "anything";
break;
// (...)
}
Αυτό το παράδειγμα δε λειτουργεί, επειδή η message δηλώνεται δύο φορές μέσα στο switch.
Θα μπορούσε να λυθεί χρησιμοποιώντας:
switch (expression) {
case 1: {
String message = "something";
break;
}
case 2: {
String message = "anything";
break;
}
// (...)
}
Καθώς το {} οριοθετεί την εμβέλεια του case.
Ωστόσο δεν είναι διαισθητικό, επειδή τα {} δεν είναι υποχρεωτικά.
Ωστόσο, αν χρησιμοποιήσεις τον νέο συμβολισμό ->, πρέπει να ακολουθείται από ένα από τα εξής: μία μόνο εντολή/έκφραση, μια εντολή throw ή ένα μπλοκ {}.
Όχι πια σύγχυση!
Μπορείς να βρεις περισσότερες πληροφορίες για το ενισχυμένο switch σε αυτό το άρθρο και σε αυτό εδώ, καθώς και στην επίσημη τεκμηρίωση της Oracle.
Επιπλέον, στη Java 21 προστέθηκε ένα χαρακτηριστικό που λέγεται Guarded Patterns, το οποίο σου επιτρέπει να κάνεις ελέγχους στην ίδια την ετικέτα του case.
String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
case "Saturday", "Sunday" -> "Weekend";
default -> "Unknown";
};
Μπορείς να βρεις περισσότερες πληροφορίες για την έκφραση switch στη Java 21 σε αυτό το blog