Может ли компилятор Java выполнять раннее связывание для нестатических методов? - PullRequest
4 голосов
/ 10 июля 2019

Допустим, у меня есть следующий класс:

public class MyClass {
    public void doSomething() {
        System.out.println("doing something.");
    }
}

Давайте далее предположим, что все, что делает мой проект, это вызывает этот .something() метод. Никаких переопределений или каких-либо других смешных дел.

MyClass myObj = new MyClass();
myObj.doSomething();

Замечает ли компилятор javac, что этот вызов метода не переопределяется, и оптимизирует привязку к "раннему связыванию"? Я прошу из любопытства; в любом реальном приложении я бы, конечно, разбросал final, static и private по всему коду.

1 Ответ

2 голосов
/ 10 июля 2019

Компилятор байт-кода (например, javac) обычно не выполняет раннее связывание для вызовов методов экземпляра:

  1. Модель Java для отдельной компиляции классов означает, что этот вид оптимизацииможет применяться только тогда, когда класс вызывает один из своих методов.(Если javac предположительно сделал раннее связывание между классами, изменение и перекомпиляция одного класса может привести к неправильной привязке.)

  2. Не так много значения, так как JITКомпилятор (или генератор компилятора AOT) - это место, где выполняется большая часть оптимизации.

Компилятор JIT в современной JVM выполняет обширную оптимизацию на основе полного набора классов, которые были загружены (до сих пор).).Это включает в себя оптимизацию диспетчеризации и встраивание вызовов методов.Кроме того, JIT-компилятор достаточно умен, чтобы отслеживать ключевые оптимизации и перекомпилировать, когда что-то вроде динамической загрузки нового класса делает недействительными предыдущие оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...