Il codice non raggiungibile è un errore in base allo Java Language Spec.
Per citare dal JLS:
The idea is that there must be some possible execution path from the beginning of the constructor, method, instance initializer or static initializer that contains the statement to the statement itself. The analysis takes into account the structure of statements. Except for the special treatment of while, do, and for statements whose condition expression has the constant value true, the values of expressions are not taken into account in the flow analysis.
Ciò significa, è che il blocco if
non viene presa in considerazione, dal momento che se si passa attraverso uno dei percorsi della dichiarazione if
, si potrebbe raggiungere la finale dichiarazione di stampa. Se è stato modificato il codice per essere:
public void foo() {
System.out.println("Hello");
if (true)
return;
else
return;
System.out.println("World!");
}
poi improvvisamente non sarebbe più a compilare, dal momento che non v'è alcun percorso attraverso l'affermazione if
che permetterebbe l'ultima riga da raggiungere.
Cioè, un compilatore compatibile con Java non è autorizzato a compilare il primo frammento di codice. Per citare ulteriormente il JLS:
As an example, the following statement results in a compile-time error:
while (false) { x=3; }
because the statement x=3; is not reachable; but the superficially similar case:
if (false) { x=3; }
does not result in a compile-time error. An optimizing compiler may realize that the statement x=3; will never be executed and may choose to omit the code for that statement from the generated class file, but the statement x=3; is not regarded as "unreachable" in the technical sense specified here.
Il secondo avvertimento che Eclipse dà, sul codice morto, è un avvertimento generato dal compilatore, che non è "irraggiungibile" , secondo il JLS, ma in pratica lo è. Questo è un ulteriore controllo di stile lint fornito da Eclipse. Questo è del tutto opzionale e, usando la configurazione di Eclipse, può essere disabilitato, o trasformato in un errore del compilatore invece di un avvertimento.
Questo secondo blocco è un "codice odore", i blocchi if (false)
vengono normalmente inseriti per disabilitare il codice per scopi di debug, averlo lasciato in genere è accidentale, e quindi l'avviso.
Infatti, Eclipse esegue test ancora più avanzati per determinare i possibili valori per un'istruzione if per determinare se sia possibile prendere entrambi i percorsi. Ad esempio, Eclipse potrebbe anche lamentarsi codice morto nel metodo seguente:
public void foo() {
System.out.println("Hello");
boolean bool = Random.nextBoolean();
if (bool)
return;
if (bool || Random.nextBoolean())
System.out.println("World!");
}
verrà generato un codice irraggiungibile per la seconda istruzione if, dal momento che può ragionare che bool
deve essere solo false
a questo punto del codice . In un frammento di codice così breve è ovvio che le due istruzioni if stanno testando la stessa cosa, tuttavia se ci sono 10-15 linee di codice nel mezzo potrebbe non essere più così ovvio.
Quindi, in sintesi, la differenza tra i due: uno è vietato dal JLS, e uno non lo è, ma viene rilevato da Eclipse come servizio per il programmatore.
Ma perché non il compilatore Java eliminare il se (vero) al momento della compilazione e quindi identificare l'errore quando analizza il codice raggiungibile? – Uri
Hey Uri, puoi sostituire "if (true)" con "boolean x = true; if (x)". Non è compito del compilatore eliminarlo, perché è possibile, ad esempio, inserire un punto di interruzione e modificare il valore di x durante l'esecuzione – Yoni
Si spera che la mia risposta (modificata un po 'dalla prima volta che l'ho vista) lo renderà un po' più chiaro. –