مانند یک دستور if/else، دستور switch به شما امکان میدهد جریان برنامه را با اجرای شرطی کد تغییر دهید. تفاوت این است که دستور switch تنها میتواند مقدار یک عبارت اولیه یا رشتهای را با مقادیر ثابت از پیش تعریفشده مقایسه کند.
هنگام استفاده از دستور switch، چند کلیدواژه مفید هستند.
switch: این کلیدواژه به شما امکان میدهد ساختار دستور switch را تعریف کنید. پس از آن، عبارت یا متغیری میآید که نتیجه را تغییر میدهد.case: از این یکی برای تعریف حالتهای مختلف نتیجه استفاده میکنید.break: کلیدواژهی break برای متوقف کردن اجرای switch در پایان جریان موردنظر بسیار مفید است. اگر آن را فراموش کنید، برنامه ادامه مییابد و ممکن است به نتایج غیرمنتظرهای منجر شود.default: همانطور که از اسمش پیداست، از آن به عنوان نتیجهی پیشفرض استفاده کنید، زمانی که هیچ case دیگری با نتیجهی عبارت شما مطابقت نمیکند.در سادهترین حالت، این دستور یک عبارت اولیه یا رشتهای را بررسی میکند و بر اساس مقدارش تصمیمی میگیرد. برای مثال:
String direction = getDirection();
switch (direction) {
case "left":
goLeft();
break;
case "right":
goRight();
break;
default:
// otherwise
markTime();
break;
}
از Java 14 به بعد (که پیشتر در 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 برای همهی مقادیر ممکن، یا با استفاده از یک 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 پیدا کنید.
علاوه بر این، قابلیتی به نام Guarded Patterns در Java 21 اضافه شد که به شما امکان میدهد بررسیها را در خود برچسب 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 را در این وبلاگ پیدا کنید.