Различия в java-байт-коде, создаваемые компиляторами Oracle и Eclipse
В нашем проекте используется инструментарий байт-кода Java. И мы наткнулись на какое-то странное поведение. Предположим, что следующий фрагмент кода:
public void a() {
new Integer(2);
}
Oracle javac компилирует приведенное выше в следующий байт-код:
0: new #2; //class java/lang/Integer
3: dup
4: iconst_2
5: invokespecial #3; //Method java/lang/Integer."<init>":(I)V
8: pop
9: return
и компилятор Eclipse в:
0: new #15; //class java/lang/Integer
3: iconst_2
4: invokespecial #17; //Method java/lang/Integer."<init>":(I)V
7: return
Как вы можете видеть, компилятор Oracle производит "dup" после "new", тогда как Eclipse этого не делает. Что совершенно верно в этом случае использования, поскольку новый экземпляр Integer не используется вообще, поэтому не требуется "dup" .
Мои вопросы:
- Есть ли некоторый обзор различий между разными компиляторами? Сообщение в статье/блоге?
- Могу ли я уверенно заключить, что если нет "dup" между "new" и "invokespecial", тогда объект не будет использоваться после инициализации?
Ответы
Ответ 1
- Могу ли я уверенно заключить, что если нет "dup" между "new" и "invokespecial", тогда объект не будет использоваться после инициализации?
Я не уверен, что вы имеете в виду, но ссылка на созданный объект может быть где-то сохранена конструктором. Поэтому вызывающий метод может не использовать объект после инициализации, но объект может быть доступен и, возможно, не будет собирать мусор, поэтому.
Ответ 2
Если существует dup между новыми и invokespecial, тогда объект обычно используется после компиляции. Например, инициализация поля обычно представляет собой последовательность new, dup, вызывает специальные и putfield. Однако в вашем примере последняя команда pop, которая очищает objectref от стека - так вы можете предположить, что этот объект не используется.
Ответ 3
Передача этой ссылки немного разорвет этот шаблон
public class Bump {
Test t;
public Bump() {
new Test(this);
}
public void setT(Test t) {
this.t = t;
}
}
И тогда для хранения результата можно использовать этот:)
public class Test {
Bump b;
public Test(Bump b) {
this.b = b;
b.setT(this);
}
}
Удачи:)