2015-11-11 27 views
7

Stavo lavorando su switch case.java 8: differenza tra class.getName() e String letterale

Se usiamo class.getName(), poi, sto ottenendo errore che "espressioni case devono essere espressioni costanti" come segue:

switch(param.getClass().getName()) 
    { 
     case String.class.getName(): 
      // to do 
      break; 
    } 

Anche se facciamo seguire, prendere stringa di nome di classe in un costante, allora anche, ottenendo lo stesso errore:

public static final String PARAM_NAME = String.class.getName(); 
switch(param.getClass().getName()) 
    { 
     case PARAM_NAME: 
      // to do 
      break; 
    } 

Ma, se io in seguito, utilizzare la stringa letterale "java.lang.String", non c'è errore:

public static final String PARAM_NAME = "java.lang.String"; 

Qualcuno può spiegare questo, perché non sta prendendo i primi due casi e sta prendendo l'ultimo? Grazie in anticipo.

risposta

8

è una chiamata al metodo e i risultati delle chiamate al metodo sono per definizione non costanti in fase di compilazione. Una stringa letterale è una costante in fase di compilazione.

Si noti che mentre molte situazioni potrebbero richiedere un riferimento a static final come una costante per la durata del programma, a switch è necessario che le sue opzioni siano codificate in fase di compilazione. Il valore di una destinazione case deve essere un valore enum o un (tempo di compilazione) ConstantExpression.

+0

Ma, lo sto prendendo anche nella variabile 'statico finale' (cioè costante), quindi anche non lo sta prendendo? –

+0

il compilatore fa un po 'di magia e presumo che le prime due cose siano compilate nello stesso identico codice byte. L'ultimo dato, lì viene usato il letterale String e quindi funziona –

+2

@KrishnaKumar Un campo 'static final' non è necessariamente una costante in fase di compilazione, anche se per scopi pratici è una costante in fase di runtime. – chrylis

6

Ogni etichetta del caso deve essere una "espressione costante". Che cosa è "un'espressione costante" è definito in linguaggio Java standard, §15.28 Constant Expressions:

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

  • Literals of primitive type and literals of type String

...

  • Simple names that refer to constant variables

Nessun metodo chiamate sono elencate lì, quindi risultato chiamata di metodo non può essere l'espressione costante anche se il metodo è banale. Ma i "nomi semplici che fanno riferimento a variabili costanti" sono elencati qui, quindi anche il riferimento alla variabile costante è una costante.

4

La ragione per questo non funziona è che il valore del case per accendere esigenze essere conosciuto al momento della compilazione (perché è hard-coded e sia allineata nel bytecode).

String.class.getName() è una chiamata di metodo che viene valutata in fase di esecuzione. Sì, static final garantisce che non cambi dopo il caricamento iniziale della classe. Ma tutto ciò è molto tempo dopo la compilazione.

Il compilatore mai chiama qualsiasi codice dal codice sorgente dell'applicazione (con la possibile eccezione dell'elaborazione delle annotazioni). Lo compila solo