Как любой, кто может ответить на этот вопрос, уже знает, JVM поддерживает несколько инструкций байт-кода для вызова методов (invokevirtual
, invokespecial
, invokestatic
, ...)
Большинство вызовов методов включенометоды экземпляра создаются с помощью invokevirtual
, но частные методы и методы инициализатора вызываются с помощью invokespecial
, как описано в спецификации JVM:
The difference between the invokespecial and the invokevirtual instructions is that
invokevirtual invokes a method based on the class of the object. The invokespecial instruction
is used to invoke instance initialization methods as well as private methods and methods of a
superclass of the current class.
Насколько я понимаю, invokevirtual
выполняет поиск в vtableразрешить метод, в то время как invokespecial
, поскольку правильная реализация метода известна во время соединения, разрешается статически.
Мой вопрос: почему invokespecial
не используется для вызова public
методов в тех случаях, когдаконкретный класс владельца метода известен во время компиляции? Мне кажется, что избегание поиска vtable было бы желательно по соображениям эффективности. Но очевидно, что в JVM есть что-то, чего я не понимаю.