2015-06-11 36 views
42

Nel codice qui sotto:Perché la variabile finale non è sempre un'espressione costante?

final int a; 
a=2; 
byte b=a; // error: possible loss of precision 

Perché ottengo questo errore? Non è a espressione costante di tempo di compilazione variabile finale e quindi implicitamente ridotto a byte durante l'assegnazione?

In altre parole non è il codice sopra equivalente a:

final int a=2; 
byte b=a; 

risposta

40

Il compilatore non è così intelligente.

Noi possiamo dire che il valore sarà sempre 2. Ma se avessimo qualcosa di simile?

class ABC{ 
    final int a; 

    public ABC(){ 
     if(Math.random() < .5){ 
      a = 2; 
     } 
     else{ 
      a = 12345; 
     } 

     byte b = a; 
    } 
} 

Il compilatore non è abbastanza intelligente da dire a questi due casi a parte, in modo che ti dà un errore, invece.

+30

Infatti il ​​compilatore non può essere così intelligente. – usr

+0

@usr Questa è una religione seria e primitiva lì. Seriamente: Perché è così? I compilatori sono sensibili ai numeri '1',' 2', '4' ed ecc. Quando si moltiplicano. Il caso in questa risposta è chiaramente irrisolvibile, perché i valori restituiti da 'random' dipendono dal momento in cui il programma inizia. – LyingOnTheSky

+9

@LyingOnTheSky Ma anche se il calcolo fosse deterministico e il compilatore potesse capirlo, non sarebbe comunque consentito trattarlo come un'espressione costante (eliminando la necessità del cast). È importante che ciò che è o non sia un programma java valido non dipende da quanto sia intelligente un particolare compilatore. – CodesInChaos

49

Dal JLS

Un vuoto final è una variabile final cui dichiarazione manca un inizializzatore.

Una variabile costante è una variabile final di tipo primitivo o tipo String che viene inizializzata con un'espressione costante (§15.28).

La variabile

final int a; 

è un vuoto final variabile . Manca un inizializzatore. Il secondo paragrafo non si applica ad esso perché non è inizializzato alla dichiarazione. Quindi non è un'espressione costante.

Questo vale anche per i campi.

2

Poiché le variabili finali possono essere ritardate inizializzate e il compilatore non può determinare per b che ha un valore nel ramo del caso.