Я знаю, что в этом коде:Является ли выражение return всегда вычисляемым или может быть оптимизировано компилятором?
public static void main(String[] args) {myMethod();}
private Object myMethod() {
Object o = new Object();
return o;
}
сборщик мусора уничтожит o
после выполнения myMethod
, поскольку возвращаемое значение myMethod
не назначен, и, следовательно, нет никаких ссылок на него. Но что, если код что-то вроде:
public static void main(String[] args) {myMethod();}
private Object myMethod() {
int i = 5;
return i + 10;
}
Будет ли компилятор даже заморачиваться обработку i + 10
, видя, как возвращаемое значение не назначается?
И если i
не был простым примитивным, но больше объект:
public static void main(String[] args) {myMethod();}
private Object myMethod() {
return new LargeObject();
}
где LargeObject
имеет дорогой конструктор, будет компилятор по-прежнему выделять память и вызов конструктора, в случае, если у него есть какие-либо побочные эффекты ?
Это было бы особенно важно, если выражение возвращаемый является сложным, но не имеет побочных эффектов, таких как:
public static void main(String[] args) {
List<Integer> list = new LinkedList();
getMiddle();
}
private Object getMiddle(List list) {
return list.get((int) list(size)/2);
}
Вызов этого метода в реальной жизни, не используя возвращаемое значение будет довольно бессмысленно, но это для примера.
Мой вопрос: учитывая эти примеры (конструктор объектов, операция на примитиве, вызов метода без побочных эффектов), может ли компилятор пропустить оператор возврата метода, если он видит, что значение не будет назначено ни на что ?
Я знаю, что могу придумать много тестов для этих проблем, но я не знаю, буду ли я им доверять. Мое понимание оптимизации кода и GC является довольно простым, но я думаю, что знаю достаточно, чтобы сказать, что обработка конкретных бит кода не обязательно обобщаема. Вот почему я спрашиваю.
Посмотрите на байтовый код (с 'javap'). Но я не думаю, что компилятор может оптимизировать вызов метода, и, следовательно, результат должен быть удален из возвращаемого стека независимо от того, использует ли его вызывающий. –
@ElliottFrisch Проблемы в моем последнем абзаце, в сочетании с примером «операция на примитивах», отчасти потому, что я задал этот вопрос. Операция на примитивах может быть очень дорогостоящей чисто арифметической операцией, и по-прежнему не будет вызова метода. – MikaelF
Был бы вызов метода, компилятор не может определить apriori, что метод не имеет побочных эффектов. –