tl; dr Meiner Meinung nach ist ein unärer +
zu verwenden, um das Unboxing auf einer der Operanden zu triggern, wenn für Wertgleichheit überprüft, und einfach die Mathematik Operatoren anderweitig zu nutzen. Begründung folgt:
Es wurde bereits erwähnt, dass ==
Vergleich für Integer
ist Identität Vergleich, die in der Regel nicht, was ein Programmierer wollen, und dass das Ziel ist, Wertvergleich zu tun; noch, ich habe ein wenig getan Wissenschaft darüber, wie dieser Vergleich am effizientesten zu tun, sowohl in Bezug auf Code Kompaktheit, Korrektheit und Geschwindigkeit.
habe ich die üblichen Bündel von Methoden:
public boolean method1() {
Integer i1 = 7, i2 = 5;
return i1.equals(i2);
}
public boolean method2() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2.intValue();
}
public boolean method3() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2;
}
public boolean method4() {
Integer i1 = 7, i2 = 5;
return i1 == +i2;
}
public boolean method5() { // obviously not what we want..
Integer i1 = 7, i2 = 5;
return i1 == i2;
}
und bekam diesen Code nach der Kompilierung und Dekompilierung:
public boolean method1() {
Integer var1 = Integer.valueOf(7);
Integer var2 = Integer.valueOf(5);
return var1.equals(var2);
}
public boolean method2() {
Integer var1 = Integer.valueOf(7);
Integer var2 = Integer.valueOf(5);
if (var2.intValue() == var1.intValue()) {
return true;
} else {
return false;
}
}
public boolean method3() {
Integer var1 = Integer.valueOf(7);
Integer var2 = Integer.valueOf(5);
if (var2.intValue() == var1.intValue()) {
return true;
} else {
return false;
}
}
public boolean method4() {
Integer var1 = Integer.valueOf(7);
Integer var2 = Integer.valueOf(5);
if (var2.intValue() == var1.intValue()) {
return true;
} else {
return false;
}
}
public boolean method5() {
Integer var1 = Integer.valueOf(7);
Integer var2 = Integer.valueOf(5);
if (var2 == var1) {
return true;
} else {
return false;
}
}
Wie man unschwer erkennen kann, Methode 1 Anrufe Integer.equals()
(offensichtlich), Methoden 2-4 Ergebnis in genau der gleiche Code, Auspacken der Werte mittels .intValue()
und dann direkt Vergleiche, und Methode 5 löst nur einen Identitätsvergleich, der die falsche Möglichkeit zum Vergleichen von Werten ist.
Da (wie bereits erwähnt beispielsweise JS) equals()
verursacht einen Overhead (es hat instanceof
und einen ungeprüften Guss zu tun), Methoden 2-4 wird mit der gleichen Geschwindigkeit genau arbeiten, noticingly Verfahren besser als 1, wenn sie in engen verwendet Schleifen, da HotSpot wahrscheinlich nicht die Casts & instanceof
optimieren wird.
Es ist ziemlich ähnlich mit anderen Vergleichsoperatoren (zB <
/>
) - sie werden Unboxing auslösen, während compareTo()
Verwendung wird nicht - aber diesmal ist der Betrieb sehr optimierbar von HS seit intValue()
nur ein Getter-Methode ist (prime Kandidat für die Optimierung).
Meiner Meinung nach, die selten verwendete Version 4 ist die prägnante Art und Weise - jeder gewürzt C/Java-Entwickler weiß, dass unäres Plus in den meisten Fällen gleich int
/.intValue()
werfen - während es ein wenig WTF sein kann Moment für einige (vor allem diejenigen, die unary plus in ihrem Leben nicht verwendet haben), zeigt es wohl am deutlichsten und am meisten kurz - es zeigt, dass wir einen int
Wert von einem der Operanden wollen, den anderen Wert zum Entpacken als Gut. Es ist auch unbestreitbar am ähnlichsten zu dem regulären i1 == i2
Vergleich, der für primitive int
Werte verwendet wird.
Meine Stimme geht für i1 == +i2
& i1 > i2
Stil für Integer
Objekte, sowohl für die Leistung & Konsistenzgründen. Es macht den Code auch für Primitive portierbar, ohne etwas anderes als die Typdeklaration zu ändern. Mit benannten Methoden scheint mir semantisches Rauschen zu erzeugen, ähnlich dem viel kritisierten Stil.
Nun, was passiert, wenn Sie versucht? Was hast du beobachtet? –
@ Bart Kiers: Ein explizites Experiment konnte nur widerlegen, nicht beweisen, dass Unboxing auftritt. Wenn Sie '==' anstelle von 'equals' verwenden, erhalten Sie das korrekte Ergebnis, möglicherweise weil die eingerahmten Zahlen intern gespeichert oder anderweitig wiederverwendet werden (vermutlich als Compiler-Optimierung). Der Grund, diese Frage zu stellen, besteht darin, herauszufinden, was intern geschieht und nicht, was scheinbar geschieht. (Zumindest deshalb bin ich hier.) –