Domanda

A cosa servono le classi anonime in Java?Possiamo dire che l'utilizzo della classe anonima è uno dei vantaggi di Java?

È stato utile?

Soluzione

Per "classe anonima", immagino tu intenda classe interna anonima.

Una classe interna anonima può rivelarsi utile quando si crea un'istanza di un oggetto con determinati "extra" come i metodi di override, senza dover effettivamente creare una sottoclasse di una classe.

Tendo a usarlo come scorciatoia per allegare un ascoltatore di eventi:

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // do something
    }
});

L'uso di questo metodo rende la codifica un po' più veloce, poiché non ho bisogno di creare una classe aggiuntiva che implementi ActionListener -- Posso semplicemente creare un'istanza di una classe interna anonima senza creare effettivamente una classe separata.

Utilizzo questa tecnica solo per compiti "veloci e sporchi" in cui creare un'intera classe sembra non necessario.Avere più classi interne anonime che fanno esattamente la stessa cosa dovrebbe essere sottoposto a refactoring in una classe reale, sia essa una classe interna o una classe separata.

Altri suggerimenti

classi interne anonime sono chiusure in modo efficace, in modo che possano essere usati per emulare le espressioni lambda o "delegati". Per esempio, prendiamo questa interfaccia:

public interface F<A, B> {
   B f(A a);
}

È possibile utilizzare questo modo anonimo per creare un funzione di prima classe in Java. Diciamo che avete il seguente metodo che restituisce il primo numero grande di quanto mi nella lista data, oppure i Se nessun numero è più grande:

public static int larger(final List<Integer> ns, final int i) {
  for (Integer n : ns)
     if (n > i)
        return n;
  return i;
}

E poi avete un altro metodo che restituisce il primo numero più piccolo di me nella lista data, oppure i Se nessun numero è più piccolo:

public static int smaller(final List<Integer> ns, final int i) {
   for (Integer n : ns)
      if (n < i)
         return n;
   return i;
}

Questi metodi sono quasi identici. Utilizzando la prima classe tipo di funzione F, possiamo riscrivere questi in un metodo come segue:

public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
   for (T t : ts)
      if (f.f(t))
         return t;
   return z;
}

È possibile utilizzare una classe anonima per utilizzare il metodo firstMatch:

F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
   Boolean f(final Integer n) {
      return n > 10;
   }
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);

Questo è un esempio molto artificiosa, ma è facile capire che essere in grado di passare le funzioni intorno come se fossero valori è una caratteristica molto utile. Vedi "può il vostro linguaggio di programmazione fare questo" da Joel se stesso.

Una bella libreria per la programmazione Java in questo stile:. Funzionale Java

classe interna

anonimo viene utilizzato in seguente scenario:

1.) per superiori (classificare Sub), Quando definizione di classe non è utilizzabile salvo caso di corrente:

class A{
   public void methodA() {
      System.out.println("methodA");
    }
}
class B{
    A a = new A() {
     public void methodA() {
        System.out.println("anonymous methodA");
     }
   };
}

2.) Per implementazione di un'interfaccia, quando è necessaria L'implementazione dell'interfaccia solo per il caso corrente:

interface interfaceA{
   public void methodA();
}
class B{
   interfaceA a = new interfaceA() {
     public void methodA() {
        System.out.println("anonymous methodA implementer");
     }
   };
}

3.) Argomento Definito classe interna anonima:

 interface Foo {
   void methodFoo();
 }
 class B{
  void do(Foo f) { }
}

class A{
   void methodA() {
     B b = new B();
     b.do(new Foo() {
       public void methodFoo() {
         System.out.println("methodFoo");
       } 
     });
   } 
 } 

li uso a volte come una sintassi incidere per Map esemplificazione:

Map map = new HashMap() {{
   put("key", "value");
}};

vs

Map map = new HashMap();
map.put("key", "value");

Si risparmia un po 'di ridondanza quando si fa un sacco di dichiarazioni put. Tuttavia, ho anche incorrere in problemi facendo questo quando la classe esterna deve essere serializzato tramite la comunicazione remota.

Sono comunemente usati come una forma prolissa di callback.

Immagino che si potrebbe dire che sono un vantaggio rispetto ai non averli, e di dover creare una classe denominata ogni volta, ma concetti simili sono implementati molto meglio in altre lingue (come chiusure o blocchi)

Ecco un esempio un'altalena

myButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        // do stuff here...
    }
});

Anche se è ancora messily verbose, è molto meglio che ti costringe a definire una classe denominata per ogni buttare via ascoltatore come questo (anche se a seconda della situazione e il riutilizzo, che possono ancora essere l'approccio migliore)

Si usa in situazioni in cui è necessario creare una classe per uno scopo specifico all'interno di un'altra funzione, per esempio, come ascoltatore, come un eseguibile (per deporre le uova un filo), ecc.

L'idea è che li si chiama da dentro il codice di una funzione in modo da non fare riferimento a loro altrove, quindi non c'è bisogno di nominarli. Il compilatore appena li enumera.

Sono zucchero essenzialmente sintattica, e dovrebbero generalmente essere spostati altrove man mano che crescono più grandi.

Non sono sicuro se si tratta di uno dei vantaggi di Java, anche se si fa usarle (e tutti noi spesso li usiamo, purtroppo), allora si potrebbe sostenere che essi sono uno.

Linee guida per Anonymous classe.

  1. classe anonima è dichiarata e inizializzata contemporaneamente.

  2. classe anonima deve estendere o implementare per una ed una sola classe o rispettivamente l'interfaccia.

  3. Come classe Anonymouse non ha un nome, può essere utilizzato una sola volta.

es:

button.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }
});

Sì, le classi interne anonime è sicuramente uno dei vantaggi di Java.

Con una classe interna anonima si ha accesso alle variabili finali e membro della classe circostante, e che torna utile in ascoltatori etc.

Ma un importante vantaggio è che il codice della classe interna, che è (almeno dovrebbe essere) strettamente accoppiati alla classe / metodo / blocco circostante, ha un contesto specifico (classe circostante, metodo e blocco).

new Thread() {
        public void run() {
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Exception message: " + e.getMessage());
                System.out.println("Exception cause: " + e.getCause());
            }
        }
    }.start();

Questo è anche uno degli esempi di tipo interna anonima con filo

io uso gli oggetti anonimi per chiamare nuove discussioni ..

new Thread(new Runnable() {
    public void run() {
        // you code
    }
}).start();

classe interna è associato con un'istanza di classe esterna e ci sono due tipi speciali: classe locale e classe anonima . Una classe anonima ci permette di dichiarare e istanziare una classe allo stesso tempo, da qui rende il codice conciso. Li usiamo quando abbiamo bisogno di una classe locale solo una volta in quanto non hanno un nome.

Si consideri l'esempio da doc dove abbiamo una Person classe:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

    String name;
    LocalDate birthday;
    Sex gender;
    String emailAddress;

    public int getAge() {
        // ...
    }

    public void printPerson() {
        // ...
    }
}

e abbiamo un metodo per stampare i membri che corrispondono criteri di ricerca come:

public static void printPersons(
    List<Person> roster, CheckPerson tester) {
    for (Person p : roster) {
        if (tester.test(p)) {
            p.printPerson();
        }
    }
}

dove CheckPerson è un'interfaccia simile:

interface CheckPerson {
    boolean test(Person p);
}

Ora possiamo fare uso di classe anonima che implementa questa interfaccia per specificare i criteri di ricerca come:

printPersons(
    roster,
    new CheckPerson() {
        public boolean test(Person p) {
            return p.getGender() == Person.Sex.MALE
                && p.getAge() >= 18
                && p.getAge() <= 25;
        }
    }
);

Ecco l'interfaccia è molto semplice e la sintassi della classe anonima sembra ingombrante e poco chiara.

Java 8 ha introdotto un termine interfaccia funzionale che è un'interfaccia con un solo metodo astratto, quindi possiamo dire Predicate è un'interfaccia funzionale. Siamo in grado di fare uso di espressione lambda che ci permette di passare la funzione come metodo di argomento come:

printPersons(
                roster,
                (Person p) -> p.getGender() == Person.Sex.MALE
                        && p.getAge() >= 18
                        && p.getAge() <= 25
        );

Si può usare un'interfaccia funzionale normale <=> al posto dell'interfaccia <=>, che ridurrà ulteriormente la quantità di codice richiesto.

classe interna anonima può essere utile dando diverse implementazioni per gli oggetti differenti. Ma dovrebbe essere usato con molta parsimonia in quanto crea problemi per la leggibilità del programma.

Uno dei principali utilizzo di classi anonime in classe-finalizzazione, che ha chiamato finalizzatore tutore . Nel mondo Java utilizzando i metodi di finalizzazione dovrebbe essere evitato fino a quando si ha realmente bisogno di loro. Bisogna ricordare, quando si modifica il metodo di finalizzazione per sottoclassi, si dovrebbe sempre richiamare super.finalize() così, perché il metodo Finalize di super classe non invocherà automaticamente ed è possibile avere problemi con le perdite di memoria.

se si considera il fatto di cui sopra, si può semplicemente utilizzare le classi anonime come:

public class HeavyClass{
    private final Object finalizerGuardian = new Object() {
        @Override
        protected void finalize() throws Throwable{
            //Finalize outer HeavyClass object
        }
    };
}

Con questa tecnica si te stesso e gli altri sviluppatori contento di chiamare HeavyClass su ogni sottoclasse del <=> che ha bisogno metodo Finalize.

È possibile utilizzare classe anonima in questo modo

TreeSet treeSetObj = new TreeSet(new Comparator()
{
    public int compare(String i1,String i2)
    {
        return i2.compareTo(i1);
    }
});

Sembra nessuno ha menzionato qui, ma si può anche utilizzare classe anonima per tenere argomento di tipo generico (che normalmente persi a causa di cancellazione del tipo) :

public abstract class TypeHolder<T> {
    private final Type type;

    public TypeReference() {
        // you may do do additional sanity checks here
        final Type superClass = getClass().getGenericSuperclass();
        this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    }

    public final Type getType() {
        return this.type;
    }
}

Se si crea un'istanza di questa classe in forma anonima

TypeHolder<List<String>, Map<Ineger, Long>> holder = 
    new TypeHolder<List<String>, Map<Ineger, Long>>() {};

allora tale holder esempio conterrà definizione non erasured di tipo passato.

Uso

Questo è molto utile per la costruzione di validatori / deserializators. Inoltre è possibile creare un'istanza di tipo generico con la riflessione (quindi se avete sempre voluto fare new T() nel tipo parametrizzato - siete i benvenuti).

Inconvenienti / Limiti

  1. Si dovrebbe passare parametro generico in modo esplicito. Non riuscendo a farlo porterà alla perdita di digitare il parametro
  2. Ogni esemplificazione vi costerà classe supplementare per essere generato dal compilatore che porta all'inquinamento classpath / vaso gonfiore

Il modo migliore per ottimizzare il codice. Inoltre, possiamo utilizzare un metodo primario di una classe o interfaccia.

import java.util.Scanner;
abstract class AnonymousInner {
    abstract void sum();
}

class AnonymousInnerMain {
    public static void main(String []k){
        Scanner sn = new Scanner(System.in);
        System.out.println("Enter two vlaues");
            int a= Integer.parseInt(sn.nextLine());
            int b= Integer.parseInt(sn.nextLine()); 
        AnonymousInner ac = new AnonymousInner(){
            void sum(){
                int c= a+b;
                System.out.println("Sum of two number is: "+c);
            }
        };
        ac.sum();
    }

}

UN Classe interna anonima viene utilizzato per creare un oggetto a cui non verrà mai più fatto riferimento.Non ha nome ed è dichiarato e creato nella stessa dichiarazione.Viene utilizzato dove normalmente utilizzeresti la variabile di un oggetto.Sostituisci la variabile con il new parola chiave, una chiamata a un costruttore e la definizione della classe al suo interno { E }.

Quando si scrive un programma threaded in Java, di solito appare così

ThreadClass task = new ThreadClass();
Thread runner = new Thread(task);
runner.start();

IL ThreadClass utilizzato qui sarà definito dall'utente.Questa classe implementerà il Runnable interfaccia necessaria per la creazione di thread.Nel ThreadClass IL run() metodo (solo metodo in Runnable) deve essere implementato.È chiaro che sbarazzarsi di ThreadClass sarebbe più efficiente ed è proprio per questo che esistono le Classi Interne Anonime.

Guarda il seguente codice

Thread runner = new Thread(new Runnable() {
    public void run() {
        //Thread does it's work here
    }
});
runner.start();

Questo codice sostituisce il riferimento fatto a task nell'esempio più in alto.Piuttosto che avere una classe separata, la classe interna anonima all'interno del file Thread() costruttore restituisce un oggetto senza nome che implementa il Runnable interfaccia e sovrascrive il file run() metodo.Il metodo run() includerebbe istruzioni all'interno che svolgono il lavoro richiesto dal thread.

Rispondendo alla domanda se le classi interne anonime siano uno dei vantaggi di Java, dovrei dire che non ne sono del tutto sicuro perché al momento non ho familiarità con molti linguaggi di programmazione.Ma quello che posso dire è che è sicuramente un metodo di codifica più semplice e veloce.

Riferimenti:Sams Teach Yourself Java in 21 giorni settima edizione

Un altro vantaggio:
Come lei sa che Java non supporta l'ereditarietà multipla, quindi se si utilizza "Thread" genere di classe come classe anonima allora la classe ha ancora uno spazio lasciato per qualsiasi altra classe di estendere.

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