Das folgende Programm druckt jeweils 'false' und 'true':
%Vor%Es wird also kein Long, sondern ein Double sein. Es funktioniert jedoch wie vorgesehen in normalen Klassen: Haben
%Vor%Dies wird 'wahr' drucken:
%Vor%bedeutet, dass es nicht wie im obigen Beispiel funktioniert.
Ich bin mir sicher, dass etwas mit Autoboxen zu tun hat, aber ist es wirklich so, wie es funktionieren sollte? Warum benutzt sie Boxen, wenn die Number-Klasse eine Superklasse von Long und Double ist, sodass der Ausdruck zu Number? Ausgewertet werden kann?
Es ist wirklich ein Schmerz, denn wenn man das n druckt, druckt es als ein doppelter Wert. (Ich weiß, es ist leicht zu umgehen, aber hat mich verrückt gemacht)
Nehmen wir das Sprachanwaltsbuch hier heraus: JLS § 15.25
Der Typ eines bedingten Ausdrucks wird wie folgt bestimmt:
- Wenn der zweite und der dritte Operand den gleichen Typ haben (was der Null-Typ sein kann), dann ist das der Typ des bedingten Ausdrucks.
Long und Double sind nicht vom selben Typ - trifft nicht zu.
- Wenn einer der zweiten und dritten Operanden vom primitiven Typ T ist und der Typ des anderen Operators das Ergebnis der Anwendung der Boxenkonvertierung ist (§5.1.7) zu T, dann ist der Typ des bedingten Ausdrucks T.
Kein Wert ist primitiv - trifft nicht zu.
- Wenn einer der zweiten und dritten Operanden vom Null-Typ ist und der Typ des anderen ein Referenz-Typ ist, dann ist der Typ des Bedingter Ausdruck ist dieser Referenztyp.
Kein Wert ist null - trifft nicht zu.
- Andernfalls, wenn der zweite und der dritte Operand konvertierbare Typen haben ( §5.1.8 ) zu numerischen Typen, dann gibt es mehrere Fälle:
- [... Sonderfälle für byte / short / char und ihre Box-Äquivalente ...]
- Andernfalls binäre numerische Werbung (§ 5.6. 2 ) wird auf die Operandentypen angewendet, und der Typ des bedingten Ausdrucks ist der hochgestufte Typ des zweiten und dritten Operanden.
Diese Regel trifft hier zu, was bedeutet, dass der Ergebnistyp des Bedingungsoperators so aussieht, als ob beide Werte entkoppelt wären. Die Annahme dahinter ist, dass sonst Number n = bool ? 1 : 2.0
und Number n = bool ? new Long(1) : new Double(2.0)
andere Werte haben. Dieses Verhalten wäre auch unerwartet und - schlimmer - inkonsistent.
Es ist einfach Schauen Sie auf den Byte-Code und Sie werden sehen (einfach Ihr Beispiel geändert)
%Vor%Bytecode
_new 'java / lang / Lang'
%Vor% Hauptpunkt ist l2d
macht die nächsten Schritte
Nimmt eine lange Ganzzahl vom Stapel ab und wandelt sie in eine doppelte Genauigkeit um Fließkommazahl, und schiebt den Doppelpunkt zurück auf den Stapel. Beachten Sie, dass dies zu einem Verlust der Genauigkeit führen kann (der Signifikanz in a Double ist 54 Bit, verglichen mit 64 Bit für den Long), aber nicht Verlust von der Größenordnung (da der Bereich eines Doppelten größer ist als der Bereich von eine lange). Die Rundung erfolgt im IEEE 754-Modus "Round-To-Nearest".
Und danach ist alles gut, also haben Sie Double Instanz, aber mit Long Value ! Wenn Sie in den Debug-Modus schauen, werden Sie sehen, dass unsere Nummer Double ist, aber Wert von Long. Sie beschreibt oben im Byte-Code
Wir können es im Byte-Code sehen
%Vor%Tags und Links java autoboxing