2016-02-04 5 views
37

Kann jemand bitte erklären, warum die folgende compiliert:Warum funktioniert das Zuweisen von short zu byte nur, wenn der short abgeschlossen ist?

final short s1 = 1; 
final char c1 = 1; 
byte b1 = s1; 
byte b2 = c1; 

Aber die folgende nicht (die Compiler Fehlermeldung Type mismatch: cannot convert from short to byte ist):

short s1 = 1; 
char c1 = 1; 
byte b1 = s1; 
byte b2 = c1; 
+0

Was sagt Ihr Compiler? – Idos

+0

Typ Mismatch: kann nicht von Kurz zu Byte konvertieren – MATH000

+0

@balalaika Ich denke, er versteht, dass er wirken kann. Er fragt, warum die ersten 4 Zeilen kein Problem für den Compiler verursachen. – GhostCat

Antwort

47

Die Antwort ist in der JLS - 5.2. Assignment Conversion:

.. wenn der Ausdruck ein konstanter Ausdruck (§15.28) vom Typ ist byte, short, char oder int:

  • Eine Verengung primitive Umwandlung kann verwendet werden, wenn der Typ der Variablen byte, short oder char ist, und Der Wert des konstanten Ausdrucks ist im Typ der Variablen darstellbar.

Wenn Sie schreiben:

final short s1 = 1; 

Der Wert des Ausdrucks ist zum Zeitpunkt der Kompilierung bekannt ist, und da es nicht geändert werden kann, brauchen Sie nicht zu werfen.

In Ihrem zweiten Snippet ist der Wert zur Kompilierzeit nicht bekannt - er wird in Laufzeit ausgewertet, so dass Sie eine explizite Besetzung benötigen.


Wenn Sie versuchen, den folgenden Code zu kompilieren:

final byte b1 = 200; 
final byte b2 = 200; 
byte sum = b1 + b1; 

Sie erhalten eine Compilation Fehlermeldung erhalten, da die Werte auf der rechten Seite bekannt an den Compiler sind und sie weiß, dass die Summe kann nicht in eine byte passen.

17

In der ersten Probe, der Compiler weiß, dass s1 und c1 wird sich nie ändern, und dass ihr endgültiger Wert (1) in byte passt.

In der zweiten, sorgt sich der Compiler, was passieren würde, wenn s1 und c1 außerhalb waren 0..255 -128..127, wenn sie einer byte Variablen zugewiesen wurden, und warnt Sie, dass es nicht sicher ist.

Wenn Sie sie explizit als Balalaika in Kommentaren vorschlagen, ist der Compiler erleichtert, dass Sie zu wissen scheinen, was Sie tun (oder zumindest jemanden, dem man die Schuld geben kann), und lassen Sie es tun es.

+0

Erstaunlich!Kannst du auf eine Erklärung zu diesem "Feature" in JLS hinweisen? –

+0

Kannst du auch erklären warum: 'final long s1 = 1; int x = s1; 'funktioniert nicht? – MATH000

+5

kann ich nicht. Die triviale Erklärung ist: die JLS erlaubt es nur für 'byte',' short', 'char' und' int' (toller Fund, Maroun Maroun - +1!). Jedoch, aber bietet keine Erklärung dafür oder für das Weglassen von "long". Meine Erklärung ergibt für mich Sinn; aber ich kann nicht herausfinden, warum "long" sich nicht so verhalten darf. – Amadan