Створення заяв про перемикання з 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;
}