2014-11-20 5 views
5

Bitte nehmen Sie sich einen Blick auf folgendes Beispiel i die Beziehung zwischen char verstehen kippe und Bytechar und Byte mit dem endgültigen Zugriffsmodifikator - java

byte b = 1; 
char c = 2; 

c = b; // line 1 

Gib mir Kompilierungsfehler, da c Art von char und b Typ byte so ist Gießen sind in gutem Zustand

aber jetzt ist die tweest hier ist, wenn ich unten Code ausführen

final byte b = 1; 
char c = 2; 

c = b; // line 2 

l ine 2 kompilieren erfolgreich spielt es keine Casting müssen bei allen so meine Frage ist, warum char c verschiedene verhalten, wenn ich mit der endgültigen Zugriffsmodifikator verwenden byte

Antwort

11

Weil es mit final Qualifying die Variable eine konstante Variable macht, die a constant expression. So

final byte b = 1; 
char c = 2; 

c = b; // line 2 

wird tatsächlich

final byte b = 1; 
char c = 2; 

c = 1; 

und die Compiler hat eine Garantie, dass der Wert 1 in einer char Variable passen.

Bei einer nicht konstanten byte Variable gibt es keine solche Garantie. byte is signed, char is unsigned.

+0

dank gotach den Punkt :) –

1

Ich vermute, dass es passiert, weil Java Compiler Referenzen auf final Variablen durch ihre Werte ersetzt (fast wie Pre-Prozessor in C). Seit Wert 1 für Typ legal ist char die letzte Zeile ist zu

umgewandelt
c = 1; 

, die erfolgreich kompiliert wird.

+0

'final' Variablen mit konstanten Ausdrücken. d.h.'Byte a = 1; endgültig b = a; char c = b; 'schlägt immer noch fehl. – weston

2

Sie sind in JLS-5.1.4 Widening and Narrowing Primitive Conversion läuft,

Die folgende Umwandlung kombiniert sowohl Verbreiterung und Verengung primitive Umwandlungen:

  • byte to char

Zuerst wird die byte auf ein int über umgewandelt Erweiterung primitive Konvertierung (§5.1.2), und dann das Ergebnis ting int wird in eine char konvertiert, indem die primitive Konvertierung (§5.1.3) eingeschränkt wird.

final byte b = 1; 
char c = (char) ((int) 2); // <-- 2 is an int literal 
c = (char) ((int) 1); // <-- b is 1 a byte literal 

Wenn Sie die bytescodes mit javap -v untersuchen sehen Sie die den Wert 1 hat bereits die Variable b nach der Kompilierung ersetzt.

public static void main(java.lang.String[]) throws java.lang.Exception; 
    descriptor: ([Ljava/lang/String;)V 
    flags: ACC_PUBLIC, ACC_STATIC 
    Exceptions: 
    throws java.lang.Exception 
    Code: 
    stack=2, locals=3, args_size=1 
     0: iconst_1 
     1: istore_1 // b = 1 
     2: iconst_2 
     3: istore_2 // c = 2 
     4: iconst_1 // integer1. 
     5: istore_2 // c = 1. 
Verwandte Themen