2015-07-03 29 views
32

Per quanto ho capito il Java 8 JLS l'espressione (1/0) è considerata un'espressione costante, ma quando provo a compilare il seguente programma con OpenJDK 8 ottengo un erroreÈ `1/0` un'espressione costante in Java?

public class Switch { 
    public static void main(String[] args) { 
     switch(42) { 
      case (1/0): 
       return; 
      default: 
       return; 
     } 
    } 
} 

L'errore dice (1/0) non è un'espressione costante

Switch.java:4: error: constant expression required 
      case (1/0): 
       ^
1 error 

Mi manca qualcosa? O è un bug in OpenJDK 8?

+0

Per quale valore ti aspetti di entrare in quel caso ?! – Biffen

+0

Non puoi davvero dividerlo a zero –

+9

Funziona se fai qualcosa di sensato, come '(1/2)'? – Armand

risposta

34

Il compilatore esegue il piegamento costante (precalcolo di espressioni letterali banali). Questo è un caso in cui l'espressione "completa bruscamente", per usare la verbosità di JLS, squalificandola dal soddisfare la definizione di "espressione costante". Quindi non è un bug, è coerente con il JLS.

E sì, l'espressione non valuta nemmeno un valore (avvisando l'utente che sta provando a fare qualcosa del genere che il risultato non sarà un'espressione costante), ma il compilatore non lo sa fino a quando non ci prova. Non valutare un valore e completare bruscamente sembrerebbe andare di pari passo.

Aggiunta una dichiarazione di variabili come

int x = 1/0; 

non causa un errore di compilazione, è l'interruttore che costringe l'espressione da valutare in fase di compilazione.

A proposito, ho verificato che ciò avvenga anche per la versione 7 di Oracle e IBM JDK, non è specifico per OpenJDK o JDK8.

+7

Sì, +1 per enfatizzare correttamente la parte "completa bruscamente" delle specifiche JLS. – sstan

+0

@sstan Sì, ho perso quella parte delle specifiche per le espressioni costanti! – ReyCharles

15

Un'espressione costante deve essere in grado di valutare un valore, poiché il compilatore deve ricondurre quell'espressione a un valore.

1/0 non ha alcun valore.

Da JSL §15.28:

Una fase di compilazione espressione costante è un'espressione denota un valore di tipo primitivo o una stringa che non completano bruscamente ed è composto utilizzando solo il seguente:

+6

Penso che l'enfasi dovrebbe essere su 'che non si completa bruscamente ', cioè gettare un' java.lang.ArithmeticException'! Buona cattura, grazie! – ReyCharles

+0

Dipende, poiché il punto è che si completa bruscamente se non ha un valore valutabile, che è il caso in questa situazione. Il "denotare un valore" è un vincolo più matematico mentre il completamento brusco è più un vincolo pragmatico.In realtà l'eccezione non viene nemmeno lanciata poiché il folding costante viene eseguito durante la compilazione non durante l'esecuzione, è un vero caso speciale. – Jack

+1

Viceversa si potrebbe dire che non ha un valore perché si completa bruscamente. Il JLS è abbastanza chiaro quando un'espressione termina bruscamente (ad esempio, la divisione intera per zero), mentre non è così piacevole usare le espressioni che indicano quando definiscono quali espressioni sono/denotano. https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15,6 – ReyCharles