Como são anônimos classes (internos) usados ​​em Java?

votos
266

O que é o uso de classes anônimas em Java? podemos dizer que o uso de classe anônima é uma das vantagens do Java?

Publicado 10/12/2008 em 06:42
fonte usuário
Em outras línguas...                            


18 respostas

votos
335

Por uma "classe anônima", Acho que você quer dizer classe interna anônima .

Uma classe interna anônima pode vir útil ao fazer uma instância de um objeto com certas "extras" como métodos de sobrecarga, sem ter que realmente subclasse uma classe.

I tendem a usá-lo como um atalho para anexar um ouvinte de evento:

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

Usando este método torna a codificação um pouco mais rápido, como eu não precisa fazer um extra classe que implementa ActionListener- eu só posso instanciar uma classe interna anônima sem realmente fazer uma classe separada.

Eu só usar esta técnica para tarefas "rápida e suja", onde fazendo uma classe inteira sente desnecessário. Ter várias classes internas anônimas que fazem exatamente a mesma coisa deve ser reformulado para uma classe real, seja ele uma classe interna ou uma classe separada.

Respondeu 10/12/2008 em 06:50
fonte usuário

votos
67

Anônimos classes internas são efetivamente encerramentos, para que eles possam ser usados ​​para imitar as expressões lambda ou "delegados". Por exemplo, ter essa interface:

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

Você pode usar este anonimamente para criar uma função de primeira classe em Java. Vamos dizer que você tem o seguinte método que retorna o primeiro número maior do que eu na lista dada, ou i se nenhum número é maior:

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

E então você tem um outro método que retorna o primeiro número menor do que eu na lista dada, ou i se nenhum número é menor:

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

Estes métodos são quase idênticos. Utilizando a primeira classe tipo de função F, podemos reescrever estes em um método como se 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;
}

Você pode usar uma classe anônima usar o método firstMatch:

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

Este é um exemplo muito artificial, mas é fácil ver que ser capaz de passar funções ao redor como se fossem valores é uma característica bastante útil. Veja "Pode sua linguagem de programação fazer isso" pelo próprio Joel.

Uma boa biblioteca para programação Java neste estilo: Java funcional.

Respondeu 10/12/2008 em 08:54
fonte usuário

votos
39

Classe interna anônima é usada no seguinte cenário:

1.) Para Overriding (Sub classing), Quando definição de classe não é utilizável, exceto caso atual:

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

2.) Para implementar uma interface, quando é necessária Aplicação do interface só para o caso atual:

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

3.) Argumento Definido Anonymous classe interna:

 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");
       } 
     });
   } 
 } 
Respondeu 09/03/2014 em 19:42
fonte usuário

votos
39

Eu usá-los, por vezes, como um hack sintaxe para Mapa instanciação:

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

vs

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

Ele salva alguma redundância ao fazer um monte de declarações de venda. No entanto, eu também tenho que correr em problemas ao fazer isso quando a classe externa precisa ser serializado através de comunicação remota.

Respondeu 11/12/2008 em 21:59
fonte usuário

votos
15

Eles são comumente usados ​​como uma forma detalhada de retorno de chamada.

Eu suponho que você poderia dizer que eles são uma vantagem em comparação com não tê-los, e ter que criar uma classe chamada de cada vez, mas conceitos semelhantes são implementadas muito melhor em outros idiomas (como encerramentos ou blocos)

Aqui está um exemplo do balanço

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

Embora ainda seja messily detalhado, é muito melhor do que forçá-lo a definir uma classe chamada para cada jogar fora ouvinte como este (embora, dependendo da situação e reutilização, que ainda pode ser a melhor abordagem)

Respondeu 10/12/2008 em 06:51
fonte usuário

votos
7

Você usá-lo em situações onde você precisa criar uma classe para uma finalidade específica dentro de outra função, por exemplo, como um ouvinte, como um executável (para gerar um segmento), etc.

A idéia é que você chamá-los de dentro do código de uma função para que você nunca se referir a eles em outros lugares, para que você não precisa nomeá-los. O compilador just enumera-los.

Eles são o açúcar essencialmente sintática, e geralmente devem ser transferidos para outros locais à medida que crescem maior.

Eu não tenho certeza se é uma das vantagens do Java, mas se você usá-los (e todos nós frequentemente usá-los, infelizmente), em seguida, você poderia argumentar que eles são um.

Respondeu 10/12/2008 em 06:50
fonte usuário

votos
6

Diretrizes para a classe anônima.

  1. classe anônima é declarado e inicializado em simultâneo.

  2. classe anônima deve estender ou implementar para uma e apenas uma classe ou interface resp.

  3. Como classe anonymouse não tem nome, ele pode ser usado apenas uma vez.

por exemplo:

button.addActionListener(new ActionListener(){

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

    }
});
Respondeu 23/05/2012 em 18:20
fonte usuário

votos
5
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();

Este é também um do exemplo para o tipo interno anónima usando rosca

Respondeu 21/03/2013 em 06:59
fonte usuário

votos
4

Sim, classes internas anônimas é definitivamente uma das vantagens de Java.

Com uma classe interna anônima que você tem acesso a variáveis ​​finais e membros da classe envolvente, e que vem a calhar em ouvintes etc.

Mas a maior vantagem é que o código de classe interior, o qual é (pelo menos deve ser) rigidamente acoplado à classe / método / bloco circundante, tem um contexto específico (a classe circundante, método e bloco).

Respondeu 10/12/2008 em 08:50
fonte usuário

votos
3

i usar objetos anônimos para chamar novos tópicos ..

new Thread(new Runnable() {
    public void run() {
        // you code
    }
}).start();
Respondeu 10/10/2013 em 06:17
fonte usuário

votos
2

Uma classe interna está associada a uma instância da classe externa e há dois tipos especiais: classe local e classe anônima . Uma classe anônima nos permite declarar e instanciar uma classe ao mesmo tempo, portanto, faz com que o concisa código. Nós usá-los quando precisamos de uma classe local apenas uma vez como eles não têm um nome.

Considere o exemplo de doc , onde temos uma Personclasse:

public class Person {

    public enum Sex {
        MALE, FEMALE
    }

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

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

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

e temos um método para imprimir em membros que correspondam critérios de pesquisa como:

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

onde CheckPersoné uma interface como:

interface CheckPerson {
    boolean test(Person p);
}

Agora nós podemos fazer uso de classe anônima que implementa essa interface para especificar critérios de pesquisa como:

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

Aqui, a interface é muito simples e a sintaxe da classe anônima parece complicado e incerto.

Java 8 introduziu um termo interface funcional que é uma interface com apenas um método abstrato, portanto, podemos dizer que CheckPersoné uma interface funcional. Podemos fazer uso de Lambda Expression que nos permite passar a função como argumento de método como:

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

Podemos usar uma interface funcional padrão Predicateno lugar da interfaceCheckPerson , que irá reduzir ainda mais a quantidade de código necessário.

Respondeu 17/11/2016 em 09:04
fonte usuário

votos
2

Classe interna anônima pode ser benéfico ao dar implementações diferentes para diferentes objetos. Mas deve ser usado com muita parcimônia, pois cria problema para a legibilidade do programa.

Respondeu 17/12/2013 em 07:59
fonte usuário

votos
1

Parece ninguém mencionou aqui, mas você também pode usar classe anônima para manter argumento de tipo genérico (que normalmente se perde devido ao tipo de apagamento) :

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 você instanciar esta classe de forma anônima

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

em seguida, tal holderinstância irá conter definição não-erasured de tipo passado.

Uso

Isto é muito útil para a construção de validadores / deserializators. Além disso, você pode criar uma instância de tipo genérico com reflexão (por isso, se você sempre quis fazer new T()no tipo parametrizada - você é bem-vindo) .

Inconvenientes / Limitações

  1. Você deve passar parâmetro genérico explicitamente. Não fazer isso irá conduzir ao tipo de perda de parâmetro
  2. Cada instanciação vai custar-lhe classe adicional a ser gerado pelo compilador que leva a classpath poluição inchaço / jar
Respondeu 17/08/2016 em 20:06
fonte usuário

votos
1

Você pode usar classe anônima desta forma

TreeSet treeSetObj = new TreeSet(new Comparator()
{
    public int compare(String i1,String i2)
    {
        return i2.compareTo(i1);
    }
});
Respondeu 03/07/2015 em 13:23
fonte usuário

votos
1

Um dos principais uso de classes anônimas na classe-finalização que chamou finalizador guardião . No mundo Java usando os métodos Finalize deve ser evitado até que você realmente precisa deles. Você tem que lembrar, quando você substituir o método finalize para sub-classes, você deve sempre invocar super.finalize(), bem como, porque o método finalize da classe super não vai chamar automaticamente e você pode ter problemas com vazamentos de memória.

Assim, considerando o fato mencionado acima, você pode apenas usar as classes anônimas como:

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

Usando esta técnica você mesmo e seus outros desenvolvedores aliviado para chamar super.finalize()em cada sub-classe do HeavyClassque precisa método finalizar.

Respondeu 28/12/2012 em 11:38
fonte usuário

votos
0

Mais uma vantagem:
Como você sabe que Java não suporta herança múltipla, por isso, se você usa "Thread" meio classe como classe anônima, em seguida, a classe ainda tem um espaço à esquerda para qualquer outra classe para estender.

Respondeu 12/05/2018 em 12:22
fonte usuário

votos
0

Um Inner classe anônima é usada para criar um objeto que nunca vai ser referenciado novamente. Não tem nome e é declarada e criado no mesmo comunicado. Isto é usado onde você usaria normalmente variável de um objeto. Você substituir a variável com a newpalavra-chave, uma chamada para um construtor e a definição de classe dentro {e }.

Ao escrever um programa de Listagem em Java, que normalmente seria parecido com este

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

O ThreadClassutilizado aqui seria definida pelo usuário. Esta classe irá implementar a Runnableinterface de que é necessário para a criação de threads. No ThreadClasso run()método (único método Runnable) precisa ser implementado também. É claro que se livrar de ThreadClassseria mais eficiente e é exatamente por isso que existem classes anônimas internas.

Olhe para o seguinte código

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

Este código substitui a referência feita para taskno mais alto exemplo. Em vez de ter uma classe separada, o interior Classe Anonymous dentro do Thread()construtor devolve um objecto não identificado que implementa a Runnableinterface e substitui o run()método. O método run()poderia incluir declarações dentro que fazem o trabalho exigido pelo segmento.

Respondendo à pergunta sobre se classes anônimas interior é uma das vantagens de Java, eu teria que dizer que eu não estou muito certo como eu não estou familiarizado com muitas linguagens de programação no momento. Mas o que eu posso dizer é que é definitivamente um método mais rápido e mais fácil de codificação.

Referências: Sams Teach Yourself Java em 21 dias Sétima Edição

Respondeu 21/03/2018 em 12:24
fonte usuário

votos
0

A melhor maneira de otimizar o código. Além disso, podemos usar para um método de substituição de uma classe ou interface.

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();
    }

}
Respondeu 14/08/2017 em 14:18
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more