Jest tam tylko jeden rodzaj instrukcji „jeśli”. Drugi to wyrażenie warunkowe. Co do tego, który będzie działał lepiej: mogą skompilować się do tego samego kodu bajtowego i spodziewałbym się, że będą się zachowywać identycznie - lub tak blisko, że zdecydowanie nie będziesz chciał wybierać jednego z nich pod względem wydajności.
Czasami if
instrukcja będzie bardziej czytelna, czasami operator warunkowy będzie bardziej czytelny. W szczególności zalecałbym użycie operatora warunkowego, gdy dwa operandy są proste i wolne od skutków ubocznych, podczas gdy jeśli głównym celem tych dwóch gałęzi są ich skutki uboczne, prawdopodobnie użyłbym if
instrukcji.
Oto przykładowy program i kod bajtowy:
public class Test {
public static void main(String[] args) {
int x;
if (args.length > 0) {
x = 1;
} else {
x = 2;
}
}
public static void main2(String[] args) {
int x = (args.length > 0) ? 1 : 2;
}
}
Dekompilacja kodu bajtowego za pomocą javap -c Test
:
public class Test extends java.lang.Object {
public Test();
Code:
0: aload_0
1: invokespecial #1
4: return
public static void main(java.lang.String[]
Code:
0: aload_0
1: arraylength
2: ifle 10
5: iconst_1
6: istore_1
7: goto 12
10: iconst_2
11: istore_1
12: return
public static void main2(java.lang.String[
Code:
0: aload_0
1: arraylength
2: ifle 9
5: iconst_1
6: goto 10
9: iconst_2
10: istore_1
11: return
}
Jak widać, jest tu niewielka różnica w istore_1
kodzie bajtowym - czy występuje w brance, czy nie (w przeciwieństwie do mojej poprzedniej bardzo błędnej próby :) ale byłbym bardzo zaskoczony, gdyby JITter skończył z innym rodzimym kodem.