Java: вызывает ли приведение типов операцию во время выполнения? - PullRequest
0 голосов
/ 19 декабря 2018

JLS утверждает, что

Специальное преобразование из типа S в тип T позволяет обрабатывать выражение типа S во время компиляции так, как если бы оно имело тип T вместо этого. В некоторых случаях для этого потребуется соответствующее действие во время выполнения, чтобы проверить правильность преобразования или преобразовать значение времени выполнения выражения в форму, подходящую для нового типа T.

Список инструкций JVM содержит

checkcast

Операция

Проверьте, принадлежит ли объект заданному типу

Object o = new String();
String s =
(String)//what does the JVM do?
o;

Так как в описании говорится, что checkcast выдает ClassCastException при сбое и проверяет, может ли objectref быть приведенным к указанному типу, я догадался, что это может быть инструкция, выполняемая во время выполнения, если я уныну в своем коде.

Прежде всего {1}: верно ли это предположение?

И если так:

Object o = (Object)//What do I do now?
new String();

{2} Это также относится к явному или явному апскейдингу?

{3} Сколько штрафов за время выполнения эта инструкция получает в масштабе другихмикрооптимизации?

В отличие от дляпример перемещения поля, содержащего ссылку на объект, в локальную переменную функции для ускорения времени доступа или другие виды микрооптимизации, сколько производительности требует checkcast?

1 Ответ

0 голосов
/ 19 декабря 2018

Точные детали, конечно, зависят от архитектуры.

Приведение примитивов и объектов в значительной степени не связано.

Для примитивных преобразований может потребоваться переместить значения между целыми числамии регистры с плавающей запятой или для расширения знака, но это, как правило, чрезвычайно быстрые операции, уменьшенные по времени доступа к памяти.

Объекты разные.

Компилятор bytecode-> native может доказать, чтопреобразование объекта всегда завершается успешно, поэтому во время выполнения никаких действий не происходит.

Обычно при успешном checkcast накладных расходов производительности практически нет.Существуют различные оптимизации (для которых где-то может быть разумное руководство).Большинство оптимизаций необходимы, даже если вы просто хотите эффективно вызывать виртуальный метод.Кроме того, дженерики - это просто «выдумка компилятора», поэтому неявные приведения очень распространены.В прежние времена абстрактные классы могли быть предпочтительнее интерфейсов из-за более простой отправки виртуальных методов, но никто не заботился о них двадцать лет.

В вашем примере кода приведение может показывать, что оно всегда выполняется успешно.В противном случае, поскольку String является окончательным, единственной необходимой проверкой является правильность информации о типе в заголовке объекта.Дальнейший доступ к памяти не требуется.

...