В обеих инструкциях используется статическая, а не динамическая отправка. Похоже, единственное существенное различие заключается в том, что invokespecial
всегда будет иметь в качестве первого аргумента объект, являющийся экземпляром класса, к которому принадлежит отправленный метод. Однако invokespecial
фактически не помещает объект туда; компилятор отвечает за то, чтобы это произошло, испустив соответствующую последовательность операций стека перед выпуском invokespecial
. Поэтому замена invokespecial
на invokestatic
не должна влиять на способ управления стеком/кучей времени выполнения, хотя я ожидаю, что это приведет к ошибке VerifyError
за нарушение спецификации.
Мне интересно узнать о возможных причинах создания двух разных инструкций, которые делают практически одно и то же. Я взглянул на источник интерпретатора OpenJDK, и кажется, что invokespecial
и invokestatic
обрабатываются почти одинаково. Имеет ли две отдельные инструкции, чтобы компилятор JIT лучше оптимизировал код, или он помогает верификатору classfile более эффективно доказывать некоторые свойства безопасности? Или это просто причуда в дизайне JVM?