2013-08-11 26 views
16

Ho 2 domande con questo segmenti di codiceparametro finale in un metodo in Java

  1. metodo 1 è soddisfacente e un metodo di lavoro 2 no. Qual è la ragione di questo?
  2. Nel metodo 1 il valore di ritorno è byte (8 bit). Ma in realtà restituiamo un valore char (16 bit). cosa sta realmente accadendo qui?

// metodo 1

static byte m1() { 
    final char c = 'b'-'a'; 
    return c; 
} 

// metodo 2

static byte m3(final char c) { 
    return c; // 3 
} 
+3

Cosa intendi per non lavorare? –

+1

durante la compilazione dice: errore: possibile perdita di precisione – chathura

+0

Forse ottimizzazione statica nel metodo 1? –

risposta

23

char in Java è un unsigned valore 16 bit, mentre byte è 8 bit firmato valore. L'intervallo consentito per il byte è [-128, 127]. Quindi, non tutti i caratteri possono essere assegnati in byte.

Nel tuo primo metodo, si restituisce un char con punto codice = 1 ('b' - 'a'). Da quando hai definito char come final e assegnandogli un'espressione costante, diventa una costante di tempo di compilazione. Quindi, il compilatore non fornisce alcun errore del compilatore.

Da JLS Section 5.2:

If the expression is a constant expression (§15.28) of type byte, short, char, or int:
- A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable.

enfasi è mia.

Tuttavia, se si fanno c non finale, sarà anche tradursi in un errore di compilazione:

static byte m1() { // This will be an error 
    char c = 'b'-'a'; 
    return c; 
} 

La ragione è, c non è un tempo di compilazione costante più, ed il compilatore non fa un implicito downcast.

Nel secondo metodo si restituisce il char passato. Il parametro c non ha una costante di tempo di compilazione. Non è noto al momento della compilazione quale valore potrebbe ottenere il metodo. Come, se si passa un char con punti di codice non nell'intervallo consentito di valore byte, non funzionerà.

per rendere il secondo metodo di lavoro, si può fare un cast esplicito:

static byte m3(final char c) { 
    return (byte)c; // 3 
} 
+0

@Babai. No. Mai lavorato su Ruby. Sono una persona di Java. –

+0

Ohh! in quale compagnia sei? –

+0

@Babai. Infosys. –

1

Nel metodo 2, il compilatore non può fare un cast implicito restringimento dalla chat al byte, perché potrebbe causare una perdita di precision (Java supporta i caratteri Unicode e il suo tipo char primitivo è definito con la dimensione di 16 bit di informazioni, a differenza del linguaggio C dove è solitamente 8 bit)

Nel metodo 1, tuttavia, il compilatore può determinare che il il valore costante 'b' - 'a' non determinerà in realtà una perdita di precisione, e quindi consente di eseguire il cast implicito.

Date un'occhiata a: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

2

Nel m1() il compilatore vede che char c è costante con un valore 1 e, pertanto, non si lamenta come si sa si può essere in forma in byte. Se lo hai modificato in final char c = 128 dove 127 è la dimensione massima dello byte, ti verrebbe un reclamo, come faresti anche quando hai rimosso il descrittore di variabile final da char c.

+0

puoi spiegare perché si è verificato un errore quando la parola chiave finale è stata cancellata? – chathura

+0

Quando rimuovi 'final' non è più una costante. Quindi il compilatore non può essere sicuro che non cambierà in futuro (anche se il metodo termina nella riga successiva, il compilatore non ne è a conoscenza). Quando c'è 'char finale c 'con valore assegnato, il compilatore lo vede come numero 127 che non ha problemi a essere trasformato in modo sicuro in qualsiasi tipo di intero. Ricorda che 'char' in java varia da 0 a 65 535 in quanto ha 16 bit. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html –

0

Ora il motivo m1() funziona e m3() non è perché in m1() c è un compile-time constant.

analizzare questo codice:

byte b = 'x'; //compile-time constant 
    int i = 'x'; //compile-time constant 
    char c = 'x'; //compile-time constant 
    c = i; //compilation error 
    c = b; //compilation error 
    b = i; //compilation error 
    b = c; //compilation error 
    i = b; // Okay 
    i = c; // Okay 

compilatore non farà un cast implicito che può eventualmente provocare la perdita dei dati, per le variabili di runtime.