2017-11-18 1 views
0

Ich verstehe nicht, warum Code-Schnipsel 1 funktioniert gut, aber Code-Schnipsel 2 gibt Zeitfehler incompatible types: java.lang.Long cannot be converted to intCasting int während Math.round (double d) in Java unter Verwendung 1.8.0_152

bezieht sich auf die Priorität der kompilieren Casting in Java? Ich bin durch diese thread on stackoverflow gegangen, aber es hat nicht geholfen.

Bitte erläutern Sie im Detail, was in den beiden Schnipsel hinter den Kulissen geschieht und warum es nicht Fehler nicht geben in Code-Schnipsel 1.

Code-Snippet 1:

package com.company; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     double dbl = 10.25; 
     int i1 = (int)Math.round(dbl); 
    } 
} 

-Code Schnipsel 2:

package com.company; 

public class Main 
{ 
    public static void main(String[] args) 
    { 
     double dbl = 10.25; 
     Long lng = Math.round(dbl); 
     int i2 = (int)lng; 
    } 
} 
+0

[Aktivieren Sie diese] (https://stackoverflow.com/a/36331461/3148590) –

+2

'int' und' long' und 'double' sind Primitive, sie können gegossen werden. 'Integer',' Long', 'Double' sind Objekte, kein Cast möglich. – Zabuza

+0

https://stackoverflow.com/questions/12514958/how-does-double-to-int-cast-work-in-java –

Antwort

1

Werfen wir einen genaueren Blick, was passiert. In Snippet 1:

double dbl = 10.25; 
int i1 = (int) Math.round(dbl); 

Sie einen double erklären. Das Ergebnis nach der Rundung ist ein long. Dann kommt eine Besetzung zu int, die möglich ist, da beide Grundtypen sind, erlaubt Java die Besetzung. Dann speichern Sie diese innerhalb int.


In Schnipsel 2 aber die Dinge ändern sich ein wenig:

double dbl = 10.25; 
Long lng = Math.round(dbl); 
int i2 = (int) lng; 

Sie deklarieren eine double, rund kehrt ein long aber Sie wollen es speichern innerhalb Long. So wandelt Java automatisch long in um, das heißt Auto-Boxen. Java kann alle primitiven Typen in ihre Wrapper-Klassen einschließen.

Zuletzt versuchen Sie zu int zu werfen, aber dies ist nicht möglich, da ein Objekt ist. Es kann jedoch automatisch Long bis long auspacken. Von dort können Sie zu int gehen. Lassen Sie uns zunächst einen Blick auf diese beiden Varianten nehmen:

int i2 = (long) lng;   // Make unboxing explicit by casting 
int i2 = lng.longValue()  // Use unboxing method 

aber es wird nicht kompiliert entweder durch:

inkompatible Typen: mögliche verlustbehaftete Umwandlung von langen

So int Die Konvertierung ist möglich, aber der Compiler warnt uns, dass eine long möglicherweise nicht in eine int (verlustreiche Konvertierung) passt, so dass es uns davon abhält.

Wir jedoch die Umwandlung es explizite durch Gießen von wieder machen kann:

int i2 = (int) lng.longValue() // The whole process completely explicit 

Oder wenn Sie Java 8, verwenden Math#toIntExact (documentation), die eine ArithmeticException wenn die long doesn werfen ‚t in die int passen:

int i2 = Math.toIntExact(lng.longValue()); 

Beachten Sie, dass Java wird nicht Entpacken Sie Ihre Long zu long und dann umwandeln sie automatisch zu int, müssen Sie das Unboxing explizit machen, wie gezeigt.

Es ist einfach eine der Casting Regeln des JVM, in diesem Fall wahrscheinlich unbeabsichtigten Fehler in der Programmierung zu verhindern.

+0

Das Ergebnis nach der Rundung ist ** nicht doppelt **. Tatsächlich gibt es "long" zurück. Bitte beachten Sie https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double- – AnV

+0

@AnV Oh, natürlich. Danke, korrigiert. – Zabuza

+0

@Holger Ja, wegen * verlustreicher Konvertierung *. Bearbeitete die Antwort, danke. – Zabuza