Pernyataan Java Switch

1. Ikhtisar

Dalam tutorial ini, kita akan mempelajari apa itu pernyataan switch dan bagaimana menggunakannya.

The beralih pernyataan memungkinkan kita untuk mengganti beberapa bersarang jika-lain konstruksi dan dengan demikian meningkatkan pembacaan kode kita.

Switch telah berkembang dari waktu ke waktu - tipe baru yang didukung telah ditambahkan, khususnya di Java 5 dan 7. Selain itu, switch terus berkembang - ekspresi switch kemungkinan akan diperkenalkan di Java 12.

Di bawah ini kami akan memberikan beberapa contoh kode untuk mendemonstrasikan penggunaan pernyataan switch , peran pernyataan break , persyaratan untuk argumen switch / nilai case dan perbandingan String dalam pernyataan switch .

Mari lanjutkan ke contoh.

2. Contoh Penggunaan

Katakanlah, kita memiliki pernyataan if-else bersarang berikut :

public String exampleOfIF(String animal) { String result; if (animal.equals("DOG") || animal.equals("CAT")) { result = "domestic animal"; } else if (animal.equals("TIGER")) { result = "wild animal"; } else { result = "unknown animal"; } return result; }

Kode di atas tidak terlihat bagus dan akan sulit untuk dipertahankan dan dipikirkan. Untuk meningkatkan keterbacaan kita dapat menggunakan pernyataan switch di sini:

public String exampleOfSwitch(String animal) { String result; switch (animal) { case "DOG": result = "domestic animal"; break; case "CAT": result = "domestic animal"; break; case "TIGER": result = "wild animal"; break; default: result = "unknown animal"; break; } return result; }

Seperti yang ditunjukkan di atas, kami membandingkan hewan argumen switch dengan beberapa nilai kasus . Jika tidak ada nilai kasus yang sama dengan argumen, maka blok di bawah label default akan dieksekusi.

Sederhananya, pernyataan break digunakan untuk keluar dari pernyataan switch .

3. Pernyataan istirahat

Meskipun sebagian besar pernyataan sakelar dalam kehidupan nyata menyiratkan bahwa hanya satu dari blok kasus yang harus dieksekusi, pernyataan putus diperlukan untuk keluar dari sakelar setelah blok selesai.

Jika kita lupa menulis break , blok di bawahnya akan dieksekusi.

Untuk mendemonstrasikan ini, mari kita hilangkan pernyataan break dan tambahkan output ke konsol untuk setiap blok:

public String forgetBreakInSwitch(String animal) { switch (animal) { case "DOG": System.out.println("domestic animal"); default: System.out.println("unknown animal"); } }

Mari jalankan kode ini forgetBreakInSwitch ( "DOG"), dan periksa hasilnya untuk membuktikan bahwa semua blok telah dieksekusi:

domestic animal unknown animal

Jadi kita harus berhati-hati dan menambahkan pernyataan break di akhir setiap blok kecuali jika ada kebutuhan untuk melewati kode di bawah label berikutnya.

Satu-satunya blok di mana pemutusan tidak diperlukan adalah yang terakhir, tetapi menambahkan pemutusan ke blok terakhir membuat kode kurang rentan terhadap kesalahan.

Kita juga dapat memanfaatkan perilaku ini untuk menghilangkan break ketika kita ingin kode yang sama dieksekusi untuk beberapa pernyataan kasus. Mari tulis ulang contoh di bagian sebelumnya dengan mengelompokkan 2 kasus pertama:

public String exampleOfSwitch(String animal) { String result; switch (animal) { case "DOG": case "CAT": result = "domestic animal"; break; case "TIGER": result = "wild animal"; break; default: result = "unknown animal"; break; } return result; }

4. ganti Argumen dan nilai case

Sekarang mari kita bahas jenis argumen switch dan nilai case yang diizinkan , persyaratannya dan cara kerja pernyataan switch dengan Strings.

4.1. Jenis Data

Kita tidak bisa membandingkan semua tipe objek dan primitif dalam pernyataan switch . Sebuah saklar hanya bekerja dengan empat primitif dan pembungkusnya, serta dengan tipe enum dan kelas String :

  • byte dan Byte
  • pendek dan pendek
  • int dan Integer
  • char dan Character
  • enum
  • Tali

Jenis string tersedia dalam pernyataan switch yang dimulai dengan Java 7.

Jenis enum diperkenalkan di Java 5 dan telah tersedia di pernyataan switch sejak saat itu.

Kelas pembungkus juga telah tersedia sejak Java 5.

Tentu saja, argumen switch dan nilai case harus berjenis sama.

4.2. Tidak ada Nilai null

Kita tidak bisa melewatkan nilai null sebagai argumen ke pernyataan switch . Jika kita melakukannya, program akan menampilkan NullPointerException, menggunakan contoh switch pertama kita :

@Test(expected=NullPointerException.class) public void whenSwitchAgumentIsNull_thenNullPointerException() { String animal = null; Assert.assertEquals("domestic animal", s.exampleOfSwitch(animal)); }

Tentu saja, kami juga tidak dapat memberikan null sebagai nilai ke label kasus dari pernyataan switch . Jika kita melakukannya, kode tidak akan dikompilasi.

4.3. Nilai Kasus sebagai Konstanta Waktu Kompilasi

Jika kita mencoba mengganti nilai case DOG dengan variabel dog , kode tidak akan dikompilasi sampai kita menandai variabel dog sebagai final :

final String dog="DOG"; String cat="CAT"; switch (animal) { case dog: //compiles result = "domestic animal"; case cat: //does not compile result = "feline" }

4.4. Perbandingan String

Jika pernyataan switch menggunakan operator persamaan untuk membandingkan string, kami tidak dapat membandingkan argumen String yang dibuat dengan operator baru ke nilai kasus String dengan benar.

Untungnya, operator sakelar menggunakan metode equals () di bawah kap mesin .

Mari kita tunjukkan ini:

@Test public void whenCompareStrings_thenByEqual() { String animal = new String("DOG"); assertEquals("domestic animal", s.exampleOfSwitch(animal)); }

5. beralih Ekspresi

JDK 13 sekarang tersedia dan menghadirkan versi perbaikan dari fitur baru yang pertama kali diperkenalkan di JDK 12: ekspresi sakelar .

Untuk mengaktifkannya, kita perlu memberikan –enable-preview ke compiler.

5.1. Ekspresi Sakelar Baru

Mari kita lihat seperti apa ekspresi sakelar baru saat berpindah bulan:

var result = switch(month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1; case MARCH, MAY, APRIL, AUGUST -> 2; default -> 0; }; 

Mengirim dalam nilai seperti Month.JUNE akan menetapkan hasil ke 3.

Notice that the new syntax uses the ->operator instead of the colon we're used to with switch statements. Also, there's no break keyword: The switch expression doesn't fall through cases.

Another addition is the fact that we can now have comma-delimited criteria.

5.2. The yield Keyword

Going a bit further, there's a possibility to obtain fine-grained control over what's happening on the right side of the expression by using code blocks. In such a case, we need to use the keyword yield:

var result = switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1; case MARCH, MAY, APRIL, AUGUST -> { int monthLength = month.toString().length(); yield monthLength * 4; } default -> 0; };

While our example is a bit arbitrary, the point here is that we've got access to more of the Java language here.

5.3. Returning Inside switch Expressions

As a consequence of the distinction between switch statements and switch expressions, it is possible to return from inside a switch statement, but we're not allowed to do so from within a switch expression.

The following example is perfectly valid and will compile:

switch (month) { case JANUARY, JUNE, JULY -> { return 3; } default -> { return 0; } }

However, the following code will not compile, as we are trying to return outside of an enclosing switch expression:

var result = switch (month) { case JANUARY, JUNE, JULY -> { return 3; } default -> { return 0; } };

5.4. Exhaustiveness

When using switch statements, it doesn't really matter if all cases are covered.

The following code, for example, is perfectly valid and will compile:

switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER -> 1; }

For switch expressions though, the compiler insists that all possible cases are covered. The following code snippet, for example, would not compile, as there's no default case and not all possible cases are covered:

var result = switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER -> 1; }

The switch expression, however, will be valid when all possible cases are covered, like in the following example:

var result = switch (month) { case JANUARY, JUNE, JULY -> 3; case FEBRUARY, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER -> 1; case MARCH, MAY, APRIL, AUGUST -> 2; }

Please note that the above code snippet does not have a default case. As long as all cases are covered, the switch expression will be valid.

6. Conclusion

Dalam tutorial ini, kita telah mempelajari seluk-beluk penggunaan pernyataan switch di Java. Kami dapat memutuskan apakah akan menggunakan sakelar berdasarkan keterbacaan dan jenis nilai yang dibandingkan.

Pernyataan switch adalah kandidat yang baik untuk kasus-kasus ketika kita memiliki sejumlah opsi dalam set yang telah ditentukan sebelumnya (misalnya: hari dalam seminggu). Jika tidak, kita harus mengubah kode setiap kali nilai baru ditambahkan atau dihapus, yang mungkin tidak dapat dilakukan. Untuk kasus ini, kita harus mempertimbangkan pendekatan lain seperti polimorfisme atau pola desain lain seperti Command.

Seperti biasa, kode JDK 8 lengkap dan kode JDK 13 tersedia di GitHub.