Em Java, as classes aninhadas podem ser static
ou não. Se estiverem static
, não contêm uma referência ao ponteiro da instância que os contém (eles também não são mais chamados de classes internas, são chamados de classes aninhadas).
Esquecer de criar uma classe aninhada static
quando não precisar dessa referência pode levar a problemas com a coleta de lixo ou a análise de escape.
É possível criar uma classe interna anônima static
também? Ou o compilador descobre isso automaticamente (o que poderia acontecer, porque não pode haver nenhuma subclasse)?
Por exemplo, se eu fizer um comparador anônimo, quase nunca preciso da referência externa:
Collections.sort(list, new Comparator<String>(){
int compare(String a, String b){
return a.toUpperCase().compareTo(b.toUpperCase());
}
}
java
syntax
inner-classes
Thilo
fonte
fonte
Collections.sort(list, String.CASE_INSENSITIVE_ORDER)
funciona desde o Java 2, leia-se, já que a API de coleção existe ...Respostas:
Não, você não pode, e não, o compilador não pode descobrir isso. É por isso que o FindBugs sempre sugere a alteração de classes internas anônimas para
static
classes aninhadas nomeadas , se elas não usarem suathis
referência implícita .Edit: Tom Hawtin - tackline diz que se a classe anônima for criada em um contexto estático (por exemplo, no
main
método), a classe anônima será de fatostatic
. Mas o JLS discorda :O Java Glossary de Roedy Green diz que o fato de classes anônimas serem permitidas em um contexto estático depende da implementação:
Edit 2: O JLS realmente cobre contextos estáticos de forma mais explícita em §15.9.2 :
Portanto, uma classe anônima em um contexto estático é aproximadamente equivalente a uma
static
classe aninhada, pois não mantém uma referência à classe envolvente, mesmo que tecnicamente não seja umastatic
classe.fonte
true
usando javac (sun-jdk-1.7.0_10) efalse
usando o compilador Eclipse.Mais ou menos. Uma classe interna anônima criada em um método estático obviamente será efetivamente estática, pois não há fonte para isso.
Existem algumas diferenças técnicas entre classes internas em contextos estáticos e classes aninhadas estáticas. Se você estiver interessado, leia o JLS 3rd Ed.
fonte
Eu acho que há um pouco de confusão na nomenclatura aqui, que, reconhecidamente, é muito boba e confusa.
Como você os chama, esses padrões (e algumas variações com visibilidade diferente) são todos possíveis, Java normais e legais:
Eles são atendidos na especificação do idioma (se você realmente se incomoda, consulte a seção 15.9.5.1 para saber o que está dentro do método estático).
Mas esta citação está completamente errada :
Eu acho que o autor citado está confundindo a palavra - chave estática com o contexto estático . (É certo que o JLS também é um pouco confuso a esse respeito.)
Honestamente, todos os padrões acima são bons (o que você chama de "aninhado", "interno", "anônimo" seja o que for ...). Realmente, ninguém removerá repentinamente essa funcionalidade no próximo lançamento do Java. Honestamente!
fonte
new
eJComponent
no seu terceiro exemplo.Classes internas não podem ser estáticas - uma classe aninhada estática não é uma classe interna. O tutorial sobre Java fala sobre isso aqui .
fonte
classes internas anônimas nunca são estáticas (elas não podem declarar métodos estáticos ou campos estáticos não finais), mas se forem definidas em um contexto estático (método estático ou campo estático), elas se comportam como estáticas no sentido de que não podem acessar membros não estáticos (ou seja, instância) da classe envolvente (como todo o resto de um contexto estático)
fonte
Na nota de tornar uma classe interna anônima estática chamando-a dentro de um método estático.
Na verdade, isso não remove a referência. Você pode testar isso tentando serializar a classe anônima e não tornando a classe anexa serializável.
fonte