Вопрос по switch-statement, java – Как работает переключатель Java под капотом?

27

Как работает оператор переключения Java под капотом? Как он сравнивает значение используемой переменной с данными в частях дела? Использует ли это== или же.equals()или это что-то совсем другое?

Меня в основном интересуют версии до 1.7.

@LouisWasserman и коробочные примитивы, поэтому вопрос все еще имеет смысл. assylias
Какая версия Java вас интересует? В 1.7 свитч тоже работает со Strings. Andrew Logvinov
Предварительно 1.7 в основном. Raghav Sood
Какой-нибудь поиск в Googlethis а такжеthis Tony R
До 1.7,switch работает только с перечислениями и примитивами, для которых== а также.equals это одно и то же. Louis Wasserman

Ваш Ответ

7   ответов
1

==

потому что для int вы не можете, например, сделать equals, а в случае enum, equals и == вернут то же самое

EDIT

Мое предположение неверно, он использует lookuptable, в байт-коде он хотел бы:

 tableswitch

что не намного быстрее, чем обычный if / else, a, как отмечали другие.

@RaghavSood: Как бы вы сравнили два примитива, не говоря уже об объектах, без какого-либо оператора сравнения? Я не вижу, как можно было бы создать оператор switch без какой-либо операции сравнения.
Есть ли каноническая ссылка, которую вы могли бы найти? Возможно ли вообще для условий случая переключения использовать сравнение, которое не равно ни ==, ни .equals ()? Raghav Sood
@Makoto Я не говорю, что операция сравнения не выполняется. Я спрашиваю, возможно ли использовать третье сравнение только с JVM, которое недоступно в API, к которому у нас есть доступ. Raghav Sood
Нет - до 1.7 Целое число было разрешено, например.
Вы должны отредактировать неправильную часть вашего ответа и утверждение, чтоtableswitch "не намного быстрее, чем обычно, если / иначе"; смешно Рассмотримswitch заявление с сотнями случаев. этоO(1) вместоO(N).
18

Neither. он используетlookupswitch Инструкция JVM, которая по сути является поиском в таблице. Взгляните на байт-код следующего примера:

  switch (1) {
  case 1:
    break;
  case 2:
    break;
  }
}

public static void main(java.lang.String[]);
  Code:
   Stack=1, Locals=1, Args_size=1
   0:   iconst_1
   1:   lookupswitch{ //2
                1: 28;
                2: 31;
                default: 31 }
   28:  goto    31
   31:  return
ссылка lookupswitch не работает, и после прочтения комментария и ответа я не уверен, что является более точным.
Это не совсем правда. Он использует переключатель поиска, если в ваших случаях есть пробелы (более одного пробела или один пробел, у которого разница значений больше 1). В противном случае он использует табличный переключатель, который более эффективен. Вы можете найти больше информации здесьartima.com/underthehood/flowP.html
Ссылка, которую я дал, не умерла, и объясняет заявления переключателя точно. Но если вы все еще не уверены, скомпилируйте оператор switch в различных случаях, а затем посмотрите на сборку Java, чтобы убедиться в этом. Eclipse фактически позволит вам скомпилировать Java, а затем открыть файл .class для чтения, и вы сможете увидеть сборку Java в вашей IDE.
0

такие как целые числа, то Java будет использовать== сравнить их Если вы используете строки, то Java будет использоватьequals() метод для проверки, если строки равны. Если вы используете оператор switch с перечислениями, то== а такжеequals() оба одинаковы, поэтому не имеет значения, какой из них используется.

2

1.Before прибытие изJava 7, это было"=="потому что мы могли бы использоватьinteger and char for switch case, and as they were primitiveтак должно было быть"==".

2. ОтJava 7, String also was allowed in switch caseи строка являетсяobject, ".equals" используется.

Я хотел бы добавить это ... что"==" используется дляcompare Object Reference Variable, not the Object itself, С помощью".equals" мыcompare the objects.

Ya .... Integer были преобразованы в int с использованием intValue () в его примитивный тип
& quot; равно и == & quot; в зависимости от типа переключаемой переменной. Или int и char преобразуются в Integer, Character?
Нет - до 1.7 Целое число было разрешено, например.
Итак, я перефразирую свой комментарий: в Java 7, учитывая, что строки разрешены в качестве переменных в операторе switch, оператор равенства равен & quot; может быть либо & quot; == & quot; или ".equals" в зависимости от типа коммутируемого вар. Или примитивные типы (int, char) упакованы в свои обертки и только ".equals" используется для единообразия.
Как до, так и после прибытия Java 7 он использовалlookupswitch а такжеtableswitchне== или же.equals().
11

этот ответ, Джаваswitch (по крайней мере, до 1.7) не всегда компилируется в== or .equals(), Вместо этого он использует поиск по таблице. Хотя это очень небольшая микрооптимизация, при большом количестве сравнений поиск таблиц почти всегда будет быстрее.

Обратите внимание, что это используется только дляswitch заявления, которые проверяют против плотных ключей. Например, проверка значения enum для всех его возможностей, вероятно, приведет к этой первичной реализации (внутренне вызываемойtableswitch).

При проверке более малонаселенных наборов ключей JVM будет использовать альтернативную систему, известную какlookupswitch, Вместо этого он будет просто сравнивать различные ключи и значения, делая по существу оптимизированный== сравнение для каждой возможности. Чтобы проиллюстрировать эти два метода, рассмотрим следующие два оператора switch:

switch (value1) {
case 0:
    a();
    break;
case 1:
    b();
    break;
case 2:
    c();
    break;
case 3:
    d();
    break;
}

switch (value2) {
case 0:
    a();
    break;
case 35:
    b();
    break;
case 103:
    c();
    break;
case 1001:
    d();
    break;
}

Первый пример, скорее всего, будет использовать поиск по таблице, в то время как другой (в основном) будет использовать== сравнение.

Я не думаю, что это правильный ответ. Тот факт, что одна JVM использует эту реализацию, не позволяет нам сделать вывод о том, что делает коммутатор в целом.
Да, достаточно справедливо.
Как видно из ответа, который вы указали,never компилируется в== или же.equals(), И поиск таблицы, безусловно,not «микрооптимизация». этоO(1) вместоO(N).
@EJP Это технически точно, ноlookupswitch семантически эквивалентно==даже если инструкции технически не совпадают.
@assylias Вопрос спрашивает, чтоswitch делает "под капотом". Хотя он может иметь разные реализации, утверждая, что он использует== или же.equals() было бы так же ложно, как этот. Я думаю, что понимание того, что стандартная JVM использует в настоящее время, является совершенно верным ответом на такой вопрос.
0

types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer. (Java 1.6)

В то время как примитивы сравниваются с==,switch метод наверняка использует этот вид сравнения в Java 1.6 (и ранее).

5

Вот

In bytecode there are two forms of switch: tableswitch and lookupswitch. One assumes a dense set of keys, the other sparse. See the description of compiling switch in the JVM spec. For enums, the ordinal is found and then the code continues as the int case. I am not entirely sure how the proposed switch on String little feature in JDK7 will be implemented.

However, heavily used code is typically compiled in any sensible JVM. The optimiser is not entirely stupid. Don't worry about it, and follow the usual heuristics for optimisation.

Вы найдете подробный ответ наВот

Похожие вопросы