Sehr abstruses Thema… Wer @kama ist, wisst ihr aber? Daher glaube ich nicht, dass die Frage auf Speicherverbrauch oder gar semantische Unterschiede abzielte, sondern eher zu einer Diskussion anregen sollte.
Zum Thema: @nillehammer s Beitrag würde ich eins zu eins unterschreiben, daher habe ich on topic derzeit nichts weiter beizutragen.
*** Edit ***
Ja, das ist so richtig. Aber der primitive Datentyp ist nicht der Wrapper, daher war die erste Aussage falsch.
ich kann nur sagen, dass ich genau eine Diskussion bzgl. der Best-Practice haben wollten…sprich für und wieder bei Rückgabe…wie der Titel schon sagt…
allein 4 weitere Antworten vor diesem Link kommentarlos hinzunehmen und dann die 5. Antwort etwas zu bemäkeln,
das liest sich in meinen Augen frech…
Finde ich persönlich ein wenig befremdlich…
Wie schon gesagt der Link beschreibt einen Artikel über Boolean/Boolean Parameter …darum ging es hier aber nicht…
Weiterhin schreibe Ich (kama) meinen Namen drunter…
[QUOTE=Jango]boolean ist ein primitiver Datentyp. Boolean eine Klasse, die ein Objekt benötigt. Oder nicht? Man kläre mich auf, bin kein Profi.[/QUOTE]Ein primitives Boolean braucht einzeln 4 und in Arrays 1 Byte pro Element. Ein Wrapper-Boolean benötigt als Objekt schon mindestens 8 Byte (oder waren es 16?).
Auf einer Oracle JVM belegt ein Boolean Objekt normalerweise 16 bytes.
4 bytes Klassenpointer + 4 bytes Object-hashcode + 1 byte für den boolean Wert
Dazu kommen dann noch 7 bytes durch das alignment auf ein vielfaches von 8 bytes.
Wenn man mehr als 32GB Heap verwendet oder CompressedOOPs deaktiviert verdoppelt sich die Größe für alle Zeiger auf 8 Bytes. Dadurch wächst der Objektheader dann auf 12 bytes. Auf die Klasse Boolean hat das durch das Alignment aber keine Auswirkungen.
Durch Optimierungen vom JIT kann sich die Größe eines Objektes angeblich auch ändern, mir ist aber nicht bekannt unter welchen Umständen das vorkommen kann.
Sehr amüsanter Thread
Viel mehr neues kann man ja nicht dazu schreiben.
Man könnte den neu ins Spiel gebrachten Aspekt von @CyborgGamma also nicht zu verwechseln von dem Spam von @CyborgBeta , in Betracht ziehen. Aber da das ja direkt abgebügelt wurde, scheint das keinen zu Interessieren. - Wobei ich finde das es Sinn macht sich den Gedanken der Enums in die Überlegungen mit ein zu beziehen, da es übersichtlicher und leicht verständlicher ist (bei mehr als 2 Zuständen).
Um genauer zu sagen, würde ich sagen das das auch eine Best Practice ist, bei mehr als 2 Zuständen einen Enum zu verwenden.
Wenn man nun Best Practices beurteilen will, würde ich sagen, das ist Rückgabewert boolean, da ich das bisher in >95% aller Fälle so in meinen bisherigen Projekten gesehen habe, ich meine da nicht nur meinen Code, sondern auch den von Kollegen, anderen Firmen,… und somit scheinbar Best Practice ist.
Was auch gefährlich ist, ist das Rückführen eines Boolean zu einem boolean
Wenn ein Wrapper Objekt (insbesondere Boolean) null ist, ist das für mich ein Fehler der nicht passieren darf.
Ein Boolean mit 3 states ist Schwachsinn, der Sinn von booleans sind Fallunterscheidungen und nicht
} else if( Boolean == Boolean.TRUE ) {
} else {
}```
Was zur Hölle ist das?
Wrapperklassen und Autoboxing wurden eingeführt damit man primitive Datentypen als Objekte behandeln kann.
Autoboxing auf einer boolean Variable durchzuführen halte ich performancetechnisch auch für wahrscheinlich marginal (kommt natürlich auf den genauen Einsatz an), aber die Frage steht trotzdem: Warum die Mehrarbeit machen wenn sie wahrscheinlich nicht genutzt wird und am Ende sowieso wieder als primitiver Datentyp verwendet wird?
Stattdessen soll der Methodenaufrufer doch stattdessen das Autoboxing durchführen wenn er z.B. für Generics ein Objekt benötigt, ist ein Zero-Liner, was spricht dagegen?
Hinzu kommt noch das Wrapperklassen immutable sind, sie sind also nicht beständig. Bei Rückgabe oder Übergabe von Objekten ist aber häufig das Ziel einer shared reference.
Es findet also ständig Boxing und Unboxing statt. Es hat eigentlich keine Vorteile außer als Generic verwendet werden zu können.
Was ist anderst an Boolean gegenüber anderen Wrappern? (Also warum frägt kama nur nach Boolean? Versuche mal die Frage anderst anzugehen, denn kama lässt nichts von seiner Intention verlauten :))
> Pooling (2 Werte, ich nehme mal ganz stark an das die gepoolt werden)
> Kaum werden Operatoren auf booleans angewendet, das boxing/autoboxing hält sich also in Grenzen
> [was noch?]
Ich sehe absolut keinen Vorteil darin standardmäßig Wrapperklassen zu verwenden (nennt mir Einen!), und das Boolean "null" annehmen kann ist definitiv ein Nachteil.
Nur wenn Wrapperklassen nicht immutable wären könnte ich mir einen generellen Einsatz vorstellen.
Nur am Rande, dass hier kann dir mit boolean nicht passieren:
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class MakeTrueFalse {
public static void main(String[] args) {
checkBoolean();
manipulateBoolean();
checkBoolean();
}
private static void manipulateBoolean() {
try {
Field field = Boolean.class.getDeclaredField("TRUE");
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(Boolean.class, false);
}
catch (Exception e) {
}
}
private static void checkBoolean() {
boolean value = getTrue();
if (value) {
System.out.println("Alles richtig");
}
else {
System.out.println("Etwas ist hier komisch");
}
}
private static Boolean getTrue() {
return true;
}
}
Ausgabe ist:
[SPOILER]
Alles richtig
Etwas ist hier komisch
[/SPOILER]
Zum eigentlichen Thema, ich würde sagen, außer bei optionalen Werten, würde ich immer boolean verwenden. Ab Java 8 nehm ich Optional, wobei ich mir ein bisschen wundere, weshalb es kein OptionalBoolean gibt.
[OT][QUOTE=Lumaraf] + 4 byte für den boolean Wert[/QUOTE]Fixed your Post.
Im ConstantPool der Klassenbeschreibung werden nur Zahlenwerte ab 4 Byte gespeichert. Einzelne boolean, byte, char und short haben deswegen auch 4 Bytes.[/ot]
[QUOTE=TMII]Ich würde mal behaupten, dass der Speicheraufwand bei Boolean und boolean exakt der selbe ist, 4byte. (nicht nachgeprüft)[/QUOTE]Irrtum. Ein Objekt (egal was für eines) hat zumindest schon mal 8 Bytes für Class- und Object-ID plus 4 oder 8 Byte pro Member. für Objekt-Member und Stringkonstanten werden 8 Byte als Referenz (oder Zeiger) abgelegt. Der Speicherumfang eines Objektes wird stets auf 8 Bytes begradigt, so dass die Anzahl der Bytes stets durch 8 teilbar ist.
[QUOTE=SlaterB]es ist doch Boolean, also gewiss nur ein Link auf eine der beiden Konstanten gemeint = 4 Byte[/QUOTE]Oh, ja… stimmt auffallend. :o
Auch im CP der Klasse haben sie nur 4 Bytes, hatte das aber anders in Erinnerung. Ausserdem gibt es sogar Daten, mit 2 (klasseninterne Referenzen wie z.B. Stringkonstanten) oder 3 Bytes (klasseninterne Referenzen auf Methoden + Methoddescriptor).
[QUOTE=Sym]Ich finde, der primitive Boolean ist auf jeden Fall lesbarer. Denn dann muss ich mir Null Gedanken machen. ;)[/QUOTE]…ausserdem werden Primitivtypen in IDEs afaik auch stets gekennzeichnet, z.B. durch Fettdruck.
(schade, kein Wortspiel. :()
[QUOTE=Spacerat][OT]Fixed your Post.
Im ConstantPool der Klassenbeschreibung werden nur Zahlenwerte ab 4 Byte gespeichert. Einzelne boolean, byte, char und short haben deswegen auch 4 Bytes.[/ot][/QUOTE]
Auf dem Stack und im ConstantPool stimmt das, da werden alle Datentypen auf 4 oder 8 bytes aufgerundet. Auf Attribute in Objekten und Arrays trifft das aber nicht zu, dort belegt ein boolean 1 byte und short/char belegen 2 bytes.