Есть ли какая-либо стоимость исполнения для Casting в Java?

Были ли различия в производительности между этими двумя кусками?

public void doSomething(Supertype input)
{
    Subtype foo = (Subtype)input;
    foo.methodA();
    foo.methodB();
}

против.

public void doSomething(Supertype input)
{
    ((Subtype)input).methodA();
    ((Subtype)input).methodB();
}

Любые другие соображения или рекомендации между этими двумя?

Ответ 1

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

Как всегда, вы должны тестировать и профилировать свой код, если вы заботитесь о производительности, но я лично лично использовал бы первую форму, просто потому, что он выглядит более читаемым для меня.

Ответ 2

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

В любом случае, если вы действительно обеспокоены эффективностью, я задаюсь вопросом, является ли Java языком, который вы должны использовать.

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

Ответ 3

Я согласен с комментарием Джона, сделайте это один раз, но для того, что стоит в общем вопросе "катится дорого", из того, что я помню: Java 1.4 значительно улучшила это с помощью Java 5, сделав отливки чрезвычайно недорогими. Если вы не пишете игровой движок, я не знаю, больше ли о чем беспокоиться. Я бы больше беспокоился об авто-боксинге/распаковке и создании скрытых объектов.

Ответ 4

В соответствии с в этой статье существует стоимость, связанная с литьем.

Обратите внимание, что статья с 1999 года, и это зависит от читателя, чтобы решить, действительно ли информация по-прежнему заслуживает доверия!

Ответ 5

В первом случае:

Subtype foo = (Subtype)input;

он определяется во время компиляции, поэтому без затрат во время выполнения.

Во втором случае:

((Subtype)input).methodA();

определяется во время выполнения, потому что компилятор не знает. Jvm должен проверить, может ли он быть преобразован в ссылку Subtype и если не выбрасывать ClassCastException и т.д. Таким образом, будет некоторая стоимость.