Я вражений тим, що ніхто фактично не опублікував якогось реального коду, який де-складається, щоб довести, що існує хоч якась незначна різниця.
Для довідки це було протестовано на javac
версії 8
, 9
і 10
.
Припустимо, цей метод:
public static int test() {
/* final */ Object left = new Object();
Object right = new Object();
return left.hashCode() + right.hashCode();
}
Збірка цього коду , як це, видає точний же байт - код , як і при final
був мати місце ( final Object left = new Object();
).
Але цей:
public static int test() {
/* final */ int left = 11;
int right = 12;
return left + right;
}
Виробляє:
0: bipush 11
2: istore_0
3: bipush 12
5: istore_1
6: iload_0
7: iload_1
8: iadd
9: ireturn
Залишаючи final
бути присутнім виробляє:
0: bipush 12
2: istore_1
3: bipush 11
5: iload_1
6: iadd
7: ireturn
Код досить зрозумілий, якщо є константа часу компіляції, він буде завантажений безпосередньо в стек операндів (він не буде зберігатися в масив локальних змінних, як це робиться в попередньому прикладі bipush 12; istore_0; iload_0
) - що має сенс оскільки ніхто не може його змінити.
З іншого боку, чому у другому випадку компілятор не виробляє, istore_0 ... iload_0
це не за межами мене, це не так, що слот 0
використовується будь-яким чином (він може зменшити масив змінних таким чином, але, можливо, у мене відсутні деякі деталі внутрішніх справ, не можу скажи точно)
Я був здивований, побачивши таку оптимізацію, враховуючи, як javac
це роблять маленькі . Як нам завжди користуватися final
? Я навіть не збираюся писати JMH
тест (який я хотів спочатку), я впевнений, що різниця в порядку ns
(якщо можливо взагалі бути захопленим). Єдине місце, в чому це може бути проблемою, це те, коли метод не може бути вписаний через його розмір (а декларування final
зменшить цей розмір на кілька байт).
Є ще два питання final
, які потрібно вирішити. По-перше, коли метод final
(з JIT
точки зору), такий метод є мономорфним - і це найулюбленіші з них JVM
.
Потім є final
змінні екземпляри (які повинні бути встановлені в кожному конструкторі); вони важливі, оскільки вони гарантують коректно опубліковані посилання, про що тут трохи доторкнулися, а також точно вказані JLS
.