Domanda

So che le classi anonime risparmiano la digitazione quando si tratta di implementare Listener e cose simili.Cercano di sostituire alcuni usi delle chiusure.

Ma cosa pensa la comunità del valore di questa caratteristica linguistica?Ha senso e lo usi regolarmente?Rende il codice più chiaro, più comprensibile e più gestibile?Oppure le classi anonime rendono il codice meno leggibile?

Qual è la tua opinione e per favore hai esempi/argomenti a portata di mano per supportare la tua opinione?

È stato utile?

Soluzione

Tendo a usare classi interne anonime in situazioni in cui non ho bisogno di avere una classe completa solo per svolgere un compito. Ad esempio, se voglio implementare un ActionListener o Runnable, ma non penso che sarebbe necessaria una classe interna. Ad esempio, per iniziare un semplice Thread, l'utilizzo di una classe interna anonima potrebbe essere più leggibile:

public void someMethod()
{
    new Thread(new Runnable() {
        public void run()
        {
            // do stuff
        }
    }).start();
}

In alcuni casi, come nell'esempio sopra, può aumentare la leggibilità, specialmente per le attività singole, poiché il codice che deve essere eseguito è tutto scritto in un punto. L'uso di una classe interna significherebbe & Quot; delocalize & Quot; il codice:

public void someMethod()
{
    new Thread(new MyRunnable()).start();
}

// ... several methods down ... //

class MyRunnable implements Runnable
{
    public void run()
    {
        // do stuff
    }
}

Detto questo, tuttavia, se ci saranno casi in cui la stessa cosa verrà ripetuta, dovrebbe in effetti essere una classe separata, che si tratti di una classe normale o di una classe interna.

Tendo a usare classi interne anonime in programmi in cui sto solo provando le cose piuttosto che averle come una caratteristica centrale di un'applicazione reale.

Altri suggerimenti

Un altro buon uso della classe interna anonima è quando è necessario inizializzare raccolte come ArrayList e Set. Questa pratica è anche nota come inizializzazione a doppia parentesi graffa Ad esempio,

private static final Set<String> VALID_CODES = new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR2D");
}};

Ovviamente, questo non è limitato alle raccolte; può essere utilizzato per inizializzare qualsiasi tipo di oggetto, ad esempio oggetti Gui:

 add(new JPanel() {{
setLayout(...);
setBorder(...);
add(new JLabel(...));
add(new JSpinner(...));
}});

La mia opinione è che le classi anonime rendono il codice meno leggibile. Per l'implementazione degli ascoltatori sono utili lezioni anonime. Per lo sviluppo di una GWT le classi anonime sono la scelta migliore. In questi casi, se non stiamo usando classi anonime, il numero di righe di codice aumenterà.

Utilizziamo regolarmente le classi anonime. Li trovo facili da usare per l'implementazione di interfacce che hanno solo uno o due metodi e che dove la funzionalità non è utilizzata altrove. Se usi di nuovo la stessa funzionalità da qualche altra parte, dovrebbe esserci una vera classe da riutilizzare.

Se l'uso della classe anonima migliora o degrada la leggibilità è una questione di gusti. Il problema principale non è sicuramente qui.

Le classi anonime, come le classi interne, portano un riferimento alla classe chiusa, rendendo così cose non private che senza di essa sarebbero. Per essere brevi, il riferimento questo della classe che racchiude può sfuggire alla classe interna. Quindi la risposta è: è una pessima pratica usare una classe interna se pubblicata da sola, dal momento che pubblicherà automaticamente la classe che la racchiude. ad esempio:

changeManager.register(new ChangeListener() {
    public void onChange(...) {
       ...
    }});

Qui, il ChangeLstener anonimo viene passato al metodo registra di un ChangeManager . In questo modo verrà automaticamente pubblicata anche la classe allegata.

Questa è sicuramente una cattiva pratica.

Uso principalmente classi anonime per interfacce con un solo metodo, ovvero Runnable o ActionListener . Le interfacce più grandi hanno garantito le proprie classi o implementazioni in una classe già esistente. E come è mia opinione, non ho bisogno di argomenti per supportarlo.

La classe anonima si trova principalmente nell'applicazione GUI appositamente per la gestione degli eventi. La classe anonima è utile nei casi di implementazione di piccole interfacce che contengono uno o due metodi ... Ad esempio .. hai una classe in cui hai due o tre thread e vuoi eseguire due o tre attività diverse usando quei thread. In questa situazione puoi prendere l'aiuto di una classe anonima per eseguire le attività desiderate. guarda il seguente esempio

class AnonymousClass{

public static void main(String args[]){


    Runnable run1=new Runnable(){

        public void run(){

            System.out.println("from run1");
        }

    };
    Runnable run2=new Runnable(){

        public void run(){

            System.out.println("from run2");
        }

    };
    Runnable run3=new Runnable(){

        public void run(){

            System.out.println("from run3");
        }

    };



    Thread t1=new Thread(run1);
    Thread t2=new Thread(run2);
    Thread t3=new Thread(run3);


    t1.run();t2.run();t3.run();

}
}

uscita:

  

da run1

     

da run2

     

da run3

Nello snap del codice sopra ho usato tre thread per eseguire tre diverse attività. Guarda, ho creato tre classi anonime che contengono l'implementazione del metodo run per eseguire tre diverse piccole attività.

Ha senso usarli, ma devi essere consapevole di ciò che viene fatto sotto. Li uso solo se ho bisogno di una classe per fare qualcosa di molto specifico che non mi serve altrove.

Dipende da cosa li confronti. Preferirei averli piuttosto che non averli, ma preferirei essere in grado di fornire semplici blocchi di codice a metodi come Arrays.sort () piuttosto che dover creare esplicitamente una classe contenente la mia implementazione di compare ().

Se limitare l'ambito e l'accesso il più possibile è una buona cosa, allora le classi anonime sono molto buone. Hanno una portata limitata all'unica classe che ne ha bisogno. Quando è appropriato, direi che le lezioni anonime sono buone.

Nel momento in cui duplicate la stessa funzione, diventa una cattiva idea. Trasformalo in una classe pubblica che si distingue da sola. Gli IDE con funzionalità di refactoring lo rendono facile.

Uso principalmente classi anonime a) notazione abbreviata se l'interfaccia ha uno o due metodi e non influirà sulla leggibilità

b) situazione in cui non sarò in grado di giustificare la creazione di una nuova classe, ad esempio In swing quando devi collegare un action listner per consentire a un JButton di eseguire un'operazione banale.

Sono d'accordo con ciò che molti altri hanno detto in quanto sono utili per le piccole interfacce se usate una sola volta. Ma aggiungerei anche la restrizione che se il codice esterno alla classe anonima deve essere modificato affinché funzioni, non utilizzare una classe anonima.

Se devi iniziare a dichiarare variabili come finali per accogliere la classe anon poiché le fa riferimento, usa invece una classe interna. Ho anche visto alcuni cattivi odori di codice in cui gli array finali (di dimensione 1) vengono utilizzati per restituire risultati da classi anon.

Non c'è nulla di intrinsecamente diverso o speciale nelle classi anonime. Alla fine sono solo zucchero sintattico con supporto per fare riferimento alla classe esterna. Ciò semplifica la creazione di adattatori, proprio come la maggior parte delle implementazioni di Iterator restituite dal framework Collections.

Le classi anonime non "nascondono" il codice ma TENDONO a renderlo leggermente meno riutilizzabile.Tieni presente che questo vale anche per le chiusure.

In un certo senso consentono alcuni refactoring interessanti perché ti è consentito passare il codice in un metodo.Questo può essere utilizzato in modo molto efficace per ridurre le duplicazioni e non sono certamente contrario alle classi/chiusure anonime, tuttavia ci sono alcuni casi in cui possono rappresentare uno svantaggio.

Innanzitutto considera che il codice anonimo della classe interna che stai passando non si presta a essere riutilizzato nel tuo codice.Se stai facendo la stessa cosa in qualche altro codice dovresti riscriverlo come qualcosa di diverso da una classe interna anonima per poterlo riutilizzare e a quel punto potrebbe essere difficile anche solo sapere che c'è del codice altrove da riutilizzo.

Oltre alla mancanza di riutilizzo c'è anche la difficoltà di parametrizzazione, il che porta alla mia più grande lamentela...tendono a portare a copiare e incollare il codice.

Ho visto parecchie GUI in cui qualcuno ha iniziato con classi interne anonime come risponditori di eventi.Molti hanno dovuto fare qualcosa di leggermente diverso, ad esempio 5 righe di codice in cui l'unica differenza è una stringa al centro.Una volta che hai preso l'abitudine di utilizzare le classi interne, la soluzione semplice è copiare e incollare il blocco e sostituire quella stringa.

La soluzione di creare una nuova classe "Nominata" che abbia un parametro stringa e passare quella classe a tutti i metodi raramente viene in mente a qualcuno a quel punto.Questa classe denominata può utilizzare parametri o ereditarietà per definire comportamenti diversi e codice.

Sono un fan delle chiusure e non odio le lezioni anonime, sto solo sottolineando alcune insidie ​​​​che ho visto.

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