2015-06-11 14 views
9

in Java,Casting Regeln für primitive Typen in Java

Es sind integrale Typen (char/short/int/long/byte)

Es gibt Gleitpunkttypen (float/double)

Es ist ein boolescher Typ (boolean), nicht ein ganzzahliger Typ, im Gegensatz zur C-Sprache.

Frage 1)

Gibt es eine allgemeine Regel (gemäß JLS zum Gießen), dass die Gespräche, welche Art in einem anderen Typ umgewandelt werden können? Aus dem gesunden Menschenverstand, ich weiß, dass, Integral- und Floating-Typ boolean Gießen nicht

erlaubt ist

Frage 2)

Bitte helfen Sie mir die Gründe für die unter Ausgabe zu verstehen:

 /* 
     * Casting rules for primitive types 
     */ 
     double aDoubleValue = 30000000000000000000.123438934; 
     int doubleToInt = (int)aDoubleValue; //stores max value 2147483647, makes sense!! 
     byte doubleToByte = (byte)aDoubleValue; //stores -1, why not 127? 
     short doubleToShort = (short)aDoubleValue; // stores -1, why not 32767? 
     long doubleToLong = (long)aDoubleValue; // stores 9223372036854775807, makes sense!! 
     float doubleToFloat = (float)aDoubleValue; // stores 3.0E19, 3.0 x 10^19 max value of float 
     char doubleToChar = (char)aDoubleValue; // what does this store? 
+4

Die Regeln für primitive Typen sind eigentlich explizit angegeben: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.2. zum Erweitern und https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3 zum Einschränken. – dhke

+0

@dhke warum '(Byte) fmax' und' (kurz) fmax' ist -1 wie in 5.1.3? irgendein Grund? – overexchange

+0

@overxchange - alles wird dort erklärt: "Die Ergebnisse können durch Untersuchung der niederwertigen Bits des minimalen und maximalen int verstanden werden. Der minimale int ist in hexadezimal 0x80000000 und der maximale int ist 0x7fffffff. Dies erklärt die kurzen Ergebnisse , die die unteren 16 Bits dieser Werte sind, nämlich 0x0000 und 0xffff, erklärt die char - Ergebnisse, die auch die niedrigen 16 Bits dieser Werte sind, nämlich '\ u0000' und '\ uffff'; Byte-Ergebnisse, die die niedrigen 8 Bits dieser Werte sind, nämlich 0x00 und 0xff. " – faramir

Antwort

11

The JLS lists

19 spezifische Umsetzungen auf primitiven Typen werden die erweiternden Grundelementkonvertierungen genannt:

  • Byte zu kurz, int, lang, float, oder doppelte
  • kurz in int, lang, float, oder Doppel
  • char in int, lang, float, oder Doppel
  • Int long, float oder double
  • lang zu schwimmen oder Doppel
  • Schwimmer verdoppeln muss

Alles andere ein explizite Besetzung Narrowing ist etwas komplexer:

  • double zu float verwendet Standard IEEE 754 Rundung.
  • Bei ganzzahligen Werten werden die höchstwertigen Bits auf die verfügbare Breite des Zieltyps reduziert. Dies kann dazu führen, dass ein Vorzeichenbit erscheint, z. (byte)0xfff == (byte)-1; Wenn der Quelltyp Fließkomma ist und der Zieltyp long ist, wird der Wert durch Runden in Richtung Null konvertiert.
  • Wenn der Quelltyp ein Fließkommawert ist und der Zieltyp ein Integral ist, aber nicht long, wird der Wert zuerst in int konvertiert, indem auf Null gerundet wird. Dann wird das Ergebnis int mit einer Integer-Konvertierung in den Zieltyp konvertiert.

Beispiele:

int doubleToInt = (int)aDoubleValue; 

Ausbeuten Integer.MAX_VALUE nach Rundungsregeln.

byte doubleToByte = (byte)aDoubleValue; 

zuerst konvertiert zu int, wodurch man Integer.MAX_VALUE und wandelt dann das zu byte. Integer.MAX_VALUE ist 0x7fffffff, daher der Byte-Wert 0xff, der -1 ist.

short doubleToShort = (short)aDoubleValue; 

gleichen wieder: wandelt in int, Integer.MAX_VALUE ergibt. 0x7fffffff bis short ergibt 0xffff, d.h. -1.

Die knifflige Sache ist eigentlich die - char Umwandlung. char ist ein einzelnes, 16-Bit-Unicode-Zeichen, daher char doubleToChar = (char)aDoubleValue gibt Ihnen '\uffff' durch die jetzt bekannten Regeln.

Wie man sehen kann, gibt es einen Unterschied zwischen Fließkomma und Integer-Verengung Operationen. Die Gleitkommaoperationen führen eine tatsächliche Rundung durch, während die Ganzzahloperationen eine bitweise Klemmung durchführen.

Die Ganzzahl-Semantik wird wahrscheinlich von C geerbt. Zumindest der erste Schritt der Float-zu-Integral-Ops ist auch, was Sie erwartet haben. Die zweiten verengenden Schritte, von Double/Float zu Short, Byte und Char, mögen ein wenig überraschend erscheinen, aber wenn Sie Float wirklich zu kurz setzen, sollten Sie wahrscheinlich überprüfen, ob Sie wissen, was Sie tun.

Verwandte Themen