С упрощенной точки зрения все методы в.Net фактически статичны. Методы экземпляров, вызываемые путем неявной передачи ссылки на this
на аргумент первого метода. Таким образом, можно вызвать метод экземпляра без фактического предоставления правильного экземпляра, заставляя его вести себя как статический метод. Например, можно вызвать string.Equals(string s)
как null.Equals(null)
либо путем динамического испускания call
OpCode вместо callvirt
либо путем записи соответствующего кода IL вручную. Насколько я помню, эта ситуация, возможно, действительно встретилась, если код был запущен во время выполнения. И не было бы проблем, если this
не используется в теле метода.
Эта вещь обеспечивает демонстрацию того, что методы действительно статичны в.Net. Я хотел бы узнать, есть ли аналогичные трюки в Java. Я просмотрел Method.invoke()
- он очень тщательно проверяет, что методы экземпляра не вызывается без правильных экземпляров, а NullPointerException
гарантируется для нулевого экземпляра. В основном потому, что все методы в Java являются виртуальными, а для виртуального вызова нужен правильный тип.
Итак, есть ли какой-либо метод вызова метода экземпляра, как если бы он был статичным в Java (возможно, из-за некоторой оптимизации, например, если в среде исполнения существует только одна реализация метода, виртуальный вызов может быть изменен на не виртуальный вызов)? Или запрещено из-за возможного существования реальных методов экземпляра (каждый экземпляр типа имеет свой собственный метод тела для этого метода, а не общий между ними)?
Конечно, не из Java-кода, нет.
Если вы используете ручной байт-код, возможно, вы можете использовать invokestatic
операцию для вызова метода экземпляра, но результат этого не определен в спецификациях JVM. Различные реализации JVM могут - и, вероятно, - обрабатывать их по-разному.