Java [best practice][Performance vs. Quellcode] Instantiierung in Verzweigungen

  • Ersteller Ersteller Tersus
  • Erstellt am Erstellt am
T

Tersus

Gast
Guten Abend,

ich stoße immer öfter auf Szenarien, wie das folgende:

Code:
...

SpecialType object = new SpecialType(value);

if(isConditionFullfilled()){

  object = new SpecialType(otherValue);

}

...

Im Falle, dass der Weg der Verzweigung eingeschlagen wird, ist die zuvor getätigte Instantiierung völlig unnötig!

Es ginge auch so:

Code:
...

SpecialType object = null;

if(isConditionFullfilled()){

  object = new SpecialType(otherValue);

}else{

  object = new SpecialType(value);

}

...

Auch, wenn es für die Meisten eine Kleinigkeit darstellt, wüsste ich doch gerne, was zu bevorzugen ist und wieso?

Das gewählte Beispiel ist primitiv. Ich weiß nicht, ob ein Compiler bei komplexeren Code-Strukturen ebenfalls optimieren kann.
 
Sehe ich jetzt auch mal wie du. Es sei' denn, die Condition ist abhängig von object. Gerade wenn SpecialType complexer ist und beim konstruieren sonst was macht, ergibt Weg 2 natürlich Sinn ...

E: Stellt sich noch die Frage, wo dir das immer öfter entgegen kommt :)
 
Zuletzt bearbeitet:
Fall 1. ist schlechter Code, bitte Fall 2. nutzen. Im Fall 1. Ein Object erzeugt, welches im Speicher abgespeichert wird. Dann wird die Referenz ersetzt und das Objekt "new SpecialType(value)" ist aber noch immer im Speicher, bis der GC das Objekt löscht. Würde man es z.B. bei großen Projekten immer tun, wäre die Speicherverschwendung enorm!
Das passiert im Fall 2. nicht, dort werden nur 4 byte (32-bit), bzw. 8 byte (64-bit) für die Initialisierung belegt.
 
Code:
if(isConditionFullfilled()){
 
  value= otherValue;
 
}

SpecialType object = new SpecialType(value);
 
Auch wenn der ein oder andere Kollege mir den Kopf abschlagen würde, würd ich es wie folgt schreiben: :D
Code:
SpecialType object = new SpecialType(isConditionFullfilled() ? otherValue : value);

Oder in anderen Worten: Ich würd Beispiel 2 bevorzugen.

Ob es performancetechnisch was ausmacht, kann ich nicht sagen
 
Wenn es nur eine Bedingung gibt, könnte man es auch so formulieren:

Code:
SpecialType object = new SpecialType(isConditionFullfilled() ? otherValue : value);

Das ist kürzer und man könnte die Variable final machen.

Wenn aber bereits abzusehen ist, dass weitere Spezialisierungen möglich sind, würde ich auch die vorgeschlagene Form wählen (ev. schon eine Methode dafür anlegen).

Wird sich in den meisten Fällen aber wohl nicht bemerkbar machen. Das Aufräumen geschieht automatisch im Hintergrund.
 
Reowulf schrieb:
Variante zwei vom OP ist effizienter (wenn wir schon über optimierung sprechen). Da wird effektiv einmal die Bedingung geprüft, und das Objekt erstellt. Du checkst die Bedingung, machst eine Zuweisung extra und erstellst dann das Objekt.
 
Habt Dank.

Das war nur ein sehr simples abkürzendes Beispiel. Da kann man tatsächlich ternäre Ausdrücke verwenden. Auch das Beispiel von Reowulf funktioniert nur, wenn die übergebenen Werte gleichen Typs sind.

Es ging ja erst mal nur ums Prinzip.
 
Dann solltest du aber auch noch das " = null" entfernen, um Hilfe von Compiler und IDE zu bekommen. Durch das if-else-Konstrukt sorgst du dafür, dass deine Variable niemals "null" sein kann. Und darauf will man sich ja auch verlassen. D.h. sobald du den if- oder else-Block entfernst, wird dir dein Compiler / IDE bescheid geben.

Gültiger Code:
Code:
SpecialType object;
 
if(isConditionFullfilled()){
  object = new SpecialType(otherValue);
}else{
  object = new SpecialType(value);
}

object.foo();

Ungültiger Code 1:
Code:
SpecialType object;

if(isConditionFullfilled()){
  object = new SpecialType(otherValue);
}else{
  
}

object.foo();

Ungültiger Code 2:
Code:
SpecialType object;

if(isConditionFullfilled()){

}else{
  object = new SpecialType(value);
}

object.foo();

Ungültiger Code 3:
Code:
SpecialType object;

if(isConditionFullfilled()){

}else{
  
}

object.foo();
 
Zurück
Oben