Створення заяв про перемикання з String
випадками було впроваджено в Java SE 7 , принаймні, через 16 років після їх першого запиту. Чітка причина затримки не була надана, але це, швидше за все, було пов'язане з роботою.
Впровадження в JDK 7
Ця функція тепер реалізована в javac
процесі "знежирення"; чистий синтаксис високого рівня, що використовує String
константи в case
деклараціях, під час компіляції розширюється на більш складний код за схемою. Отриманий код використовує інструкції JVM, які існували завжди.
Під час компіляції A switch
зі String
справами перекладається на два перемикачі. Перший відображає кожен рядок в унікальне ціле число - його положення в вихідному комутаторі. Це робиться, попередньо увімкнувши хеш-код мітки. Відповідний випадок - це if
твердження, яке перевіряє рівність рядків; якщо на хеші є зіткнення, тест є каскадним if-else-if
. Другий перемикач відображає зображення у вихідному вихідному коді, але замінює мітки регістрів відповідними позиціями. Цей двоетапний процес дозволяє легко зберегти контроль потоку вихідного вимикача.
Вимикачі в JVM
Для отримання більш детальної технічної глибини switch
можна звернутися до специфікації JVM, де описана компіляція операторів комутації . У двох словах, є дві різні інструкції JVM, які можна використовувати для комутатора, залежно від рідкості констант, що використовуються у випадках. Обидва залежать від використання цілих констант для кожного випадку для ефективного виконання.
Якщо константи щільні, вони використовуються як індекс (після віднімання найменшого значення) до таблиці покажчиків інструкцій - tableswitch
інструкції.
Якщо константи рідкі, виконується двійковий пошук правильного випадку - lookupswitch
інструкція.
У знежиренні a switch
на String
об'єктах, ймовірно, будуть використані обидві інструкції. Це lookupswitch
підходить для першого вмикання хеш-кодів, щоб знайти початкове положення корпусу. Отримана порядкова норма - це природне пристосування для а tableswitch
.
Обидві інструкції вимагають сортування цілих констант, призначених для кожного випадку, під час компіляції. Під час виконання, хоча O(1)
ефективність, як tableswitch
правило, виявляється кращою, ніж O(log(n))
продуктивність lookupswitch
, вона вимагає певного аналізу, щоб визначити, чи таблиця достатньо щільна, щоб виправдати проміжок часу та часу. Білл Веннерс написав чудову статтю, яка детальніше висвітлює цю проблему , а також детально ознайомлюється з іншими інструкціями щодо управління потоком Java.
До JDK 7
До JDK 7, enum
міг наблизити String
перемикач на основі. Для цього використовується статичнийvalueOf
метод, сформований компілятором для кожного enum
типу. Наприклад:
Pill p = Pill.valueOf(str);
switch(p) {
case RED: pop(); break;
case BLUE: push(); break;
}