2014-06-17 15 views
5

In Java 1.8, non è necessario definire un campo come final in modo che sia tratto dalle classi anonime.Campo di classi anonimi che accedono alla compatibilità con Java 1.8 con le versioni precedenti

Per esempio, su versioni precedenti:

public void foo(final int bar) { 
    new Runnable() { 
    public void run() { 
     System.out.println(bar); 
    } 
    }; 
} 

Ma, ora, su Java 1.8, bar non ha bisogno di essere definitiva:

public void foo(int bar) { 
    new Runnable() { 
    public void run() { 
     System.out.println(bar); 
    } 
    }; 
} 

Quindi, se io compilo il mio progetto, e l'unica risorsa implementata su Java 1.8 che sto usando è questa (non sto usando nessun lambda, nuove classi, ecc.), il mio codice sarà eseguibile su computer con versioni Java precedenti? Se no, perché?

+3

si potrebbe perdere questo [Differenza tra finale e in modo efficace finale] (http://stackoverflow.com/questions/20938095/difference-between-final-and-effectively-final) –

+2

'javac' semplicemente non ti permette di combinare' -source 1.8' con '-target 1.7'. – Holger

+0

Uscire dalla tangente, ma non vorrei inserire il codice in 1.8 senza dichiarare esplicitamente il mio argomento finale o le variabili come * final *. A differenza di altri linguaggi in cui args e vars sono effettivamente immutabili per impostazione predefinita, Java, il linguaggio, li ha sempre resi mutabili, per impostazione predefinita. Così ora, Java 1.8 sta facendo questa magia dietro le quinte che sfuma efficacemente la linea di ciò che è mutevole e ciò che non lo è. Un'idea terribile per quanto riguarda la leggibilità del codice. –

risposta

6

Quando si compila con -target 1.8, javac emetterà file di classe con un numero di versione di 52.0 che non è supportato dalle JVM precedenti. Quindi, anche se è l'unica differenza che ti impedisce di eseguire file compilati con -target 1.8.

E javac non supporta specificando -source 1.8 e -target 1.7 allo stesso tempo. Produrrà il messaggio di errore source release 1.8 requires target release 1.8.

Tuttavia, se si utilizzano efficacemente variabili finali è l'unica funzionalità di Java 8 che si sta utilizzando, non vi è alcuna differenza di codice byte oltre al numero di versione. Se si compila tale codice di targeting 1.8 e si corregge i file di classe riducendo il numero di versione a 51.0, verranno eseguiti su Java 7. È semplice come ridurre il byte all'indice 7 di uno.

La parte difficile è quello di disciplinare te stesso a non utilizzare altre funzioni Java 8 quando si utilizza un compilatore Java 8 se si desidera creare Java 7 codice compatibile ...

1

Penso che Java 8 abbia cambiato la versione principale del file di classe in modo diverso rispetto a Java 7, quindi una JVM più vecchia probabilmente non sarà in grado di caricare le classi più recenti.

Se si compila con un -target 1.7, non so se è possibile utilizzare in modo efficace finale

0

Se si compila il codice senza -target 1.7 -source 1.7 verrà compilato per la versione più recente bytecode e vecchia JVM non poteva correre come classi.

Se si compila il vostro esempio con -target 1.7 -source 1.7 opzioni - complicazione fallirà con il messaggio

error: local variable bar is accessed from within inner class; needs to be declared final 
           System.out.println(bar); 
               ^

così, la risposta è NO, non è possibile eseguire tale codice sul vecchio JVM di

Problemi correlati