Riferendosi ai campi non finali di classe contenitrice all'interno di una classe interna anonima in Java

StackOverflow https://stackoverflow.com/questions/2248970

Domanda

In Java, lo so che è possibile fare qualcosa di simile a questo:

public class Greeter {
    public void greetEventually() {
        final String greeting = "Hello!";
        Job j = new Job() {
            public void run() {
                System.out.println(greeting);
            }
        };
        j.schedule();
    }
}

Ciò eseguire il Job anonima ad un certo punto in futuro. Questo funziona perché le classi anonime sono autorizzati a fare riferimento alle variabili finali nel perimetro che racchiude.

Quello che non sono sicuro circa è il caso seguente:

public class Greeter {
    private String greeting;

    // ... Other methods that might mutate greeting ...

    public void greetEventually() {
        Job j = new Job() {
            public void run() {
                System.out.println(greeting);
            }
        };
        j.schedule();
    }
}

In questo caso il mio Job anonima si riferisce ad un campo non finale della classe contenitrice. Quando viene eseguito il lavoro, io vedo il valore del campo greeting come lo era quando il lavoro è stato creato, o come è quando è in esecuzione? Penso di sapere la risposta, ma ho pensato che fosse una domanda interessante, e in un primo momento io e un paio di colleghi stessi ripensamenti per qualche minuto. Lasciai

È stato utile?

Soluzione

Vedrai il valore di greeting come lo è quando il Job anonima esegue.

Il modificatore final è richiesto solo per le variabili locali, non variabili membro.

Altri suggerimenti

Si accede attraverso il campo (l'esterno) this). Si può pensare di this nel modo più efficace una variabile locale final. il locale è unico final, l'oggetto puntato non è (necessariamente) costante. Immaginate una variabile locale con lo stesso valore this e dovrebbe essere chiaro.

public class Greeter {
    private String greeting;

    // ... Other methods that might mutate greeting ...

    public void greetEventually() {

        private final Greeter greeter = this; // <---

        Job j = new Job() {
            public void run() {
                System.out.println(   greeter.greeting   ); // <---
            }
        };
        j.schedule();
    }
}

Il modificatore finale si applica alle variabili locali solo per fornire variabili per ogni istanza della classe interna, in modo da usare: def saluto String;

Quando avete bisogno di una sola istanza della variabile (come il caso di costanti o risorse comuni), l'uso: String greeting privato;

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top