Domanda

Non immaginavo che avrei incontrato una sintassi radicalmente nuova in Java in questa fase, ma ecco, ho appena incontrato qualcosa:

Il contesto esatto e ciò che il codice seguente dovrebbe fare è abbastanza irrilevante: è lì solo per dare un qualche tipo di contesto.

Sto cercando di creare sinteticamente un evento in IT Mill Toolkit, quindi ho scritto questo tipo di linea:

buttonClick(new Button.ClickEvent(button));

Ma Eclipse mi dà il seguente messaggio di errore:

  

Non è accessibile alcuna istanza chiusa di tipo Button. Deve qualificare l'allocazione con un'istanza chiusa di tipo Button (ad esempio x.new A () dove x è un'istanza di Button).

Quando riscrivo la riga sopra come segue, non mi lamento più:

buttonClick(button.new ClickEvent(button)); // button instanceof Button

Quindi, la mia domanda è: Cosa significa esattamente quest'ultima sintassi e perché il primo frammento non funziona? Di cosa si lamenta Java e cosa sta facendo nella seconda versione?

Informazioni sullo sfondo: sia Button che Button.ClickEvent sono classi pubbliche non astratte.

È stato utile?

Soluzione

Le classi interne (come Button.ClickEvent ) necessitano di un riferimento a un'istanza della classe esterna ( Button ).

Tale sintassi crea una nuova istanza di Button.ClickEvent con il riferimento di classe esterno impostato sul valore di button .

Ecco un esempio: ignora la mancanza di incapsulamento, ecc., è solo a scopo dimostrativo:

class Outer
{
    String name;

    class Inner
    {
        void sayHi()
        {
            System.out.println("Outer name = " + name);
        }
    }
}

public class Test
{
    public static void main(String[] args)
    {
        Outer outer = new Outer();
        outer.name = "Fred";

        Outer.Inner inner = outer.new Inner();
        inner.sayHi();
    }
}

Vedi sezione 8.1.3 delle specifiche per ulteriori informazioni sulle classi interne e le istanze di chiusura.

Altri suggerimenti

Button.ClickEvent è una classe interna non statica, quindi un'istanza di questa classe può esistere solo racchiusa in un'istanza di Button.

Nel tuo secondo esempio di codice hai un'istanza di Button e crei un'istanza di ClickEvent racchiusa in questa istanza di Button ...

Una classe interna non statica in Java contiene un riferimento nascosto che punta a un'istanza della classe esterna in cui è dichiarata. Quindi il messaggio di errore che hai originariamente ti dice che non puoi creare una nuova istanza della classe interna senza specificare anche un'istanza della classe esterna a cui collegarla.

Forse la ragione per cui non hai mai visto quella sintassi prima è che le classi interne sono spesso allocate in un metodo della classe esterna, in cui il compilatore si occupa automaticamente di questo.

Per evitare di confondere te stesso e gli altri programmatori con questa funzione usata raramente puoi sempre rendere statiche le classi interne.

Nel caso in cui sia necessario un riferimento alla classe esterna, puoi passarla esplicitamente nel costruttore.

In realtà puoi farlo , ma devi dichiarare ClickEvent come static all'interno del pulsante , e quindi non dovresti avere problemi ad usare la tua sintassi:

buttonClick(new Button.ClickEvent(button));

Fondamentalmente statico fa in modo che la classe ClickEvent appartenga direttamente alla classe Button anziché a un'istanza specifica (ad esempio new Button () ) del pulsante .


Seguendo l'esempio di @Jon Skeet:

// Button.java
class Button
{

    public static class ClickEvent
    {
        public ClickEvent(Button b)
        {
            System.out.println("Instance: " + this.toString());
        }
    }
}

// Test.java
public class Test
{
    public static void main(String[] args)
    {
        Button button = new Button();
        buttonClick(new Button.ClickEvent(button));
    }

    public static void buttonClick (Button.ClickEvent ce) {
    }
}

Il tuo codice verrebbe compilato, se avessi digitato

buttonClick(new Button().ClickEvent(button));

anziché

buttonClick (nuovo Button.ClickEvent (pulsante));

come costruttore è un metodo e quando si chiama un metodo in Java è necessario passare l'elenco degli argomenti, anche quando è vuoto.

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