Я поражен тем, что никто на самом деле не опубликовал какой-то реальный код, который был скомпилирован, чтобы доказать, что существует хотя бы небольшая разница.
Для справки это было протестировано против версии javac
8
, 9
и 10
.
Предположим, что этот метод:
public static int test() {
/* final */ Object left = new Object();
Object right = new Object();
return left.hashCode() + right.hashCode();
}
Компилируя этот код как есть, создает точный тот же самый байтовый код, что и при final
.
Но этот:
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
(который я хотел изначально), я уверен, что diff находится в порядке ns
(если возможно вообще быть захвачен). Единственное место, где это может быть проблемой, - это когда метод не может быть встроен из-за его размера (и объявление final
уменьшит этот размер на несколько байтов).
Есть еще два final
s, которые необходимо решить. Во-первых, когда метод final
(с точки зрения JIT
), такой метод является мономорфным - и это самые любимые единицы JVM
.
Тогда есть final
переменные экземпляра (которые должны быть установлены в каждом конструкторе); они важны, поскольку они гарантируют корректно опубликованную ссылку, , как это немного коснулось здесь , а также точно указано в JLS
.
Это выглядит странным, но это работает. Мы выполняем в нем приблизительно 20 различных мест в нашем приложении. Hyperlink
неявно конструкции <Run/>
при помещении текста в его "содержание", но в.NET 3.5 <Run/>
, не позволят Вам связать с ним, таким образом, необходимо будет явно использовать TextBlock
.
<TextBlock>
<Hyperlink Command="local:MyCommands.ViewDetails" CommandParameter="{Binding}">
<TextBlock Text="{Binding Path=Name}"/>
</Hyperlink>
</TextBlock>
<час> Обновление : Обратите внимание на это с.NET 4.0 эти Выполнение. Текстовое свойство может теперь быть связано:
<Run Text="{Binding Path=Name}" />
У меня это сработало на «Странице».
<TextBlock>
<Hyperlink NavigateUri="{Binding Path}">
<TextBlock Text="{Binding Path=Path}" />
</Hyperlink>
</TextBlock>