sintaxe estranho para instanciar uma classe interna
-
10-07-2019 - |
Pergunta
Eu não imaginava que eu iria encontrar radicalmente nova sintaxe em Java mais nesta fase, mas eis que, eu só encontrou algo:
O contexto exato e que o código abaixo deve fazer é bastante irrelevante -. Ele está lá apenas para dar algum tipo de contexto
Eu estou tentando criar sinteticamente um evento em TI Moinho Toolkit, então eu escrevi este tipo de linha:
buttonClick(new Button.ClickEvent(button));
Mas, Eclipse me dá a seguinte mensagem de erro:
No caso de inclusão do tipo Button é acessível. Deve qualificar a atribuição com um exemplo de vedante tipo botão (por exemplo x.new A () em que x é um exemplo de botão).
Quando eu reescrever a linha acima da seguinte forma, ele não reclamar mais:
buttonClick(button.new ClickEvent(button)); // button instanceof Button
Então, minha pergunta é:? O que significa a última média sintaxe, exatamente, e por que não o primeiro trabalho trecho O que é Java reclamando, e o que está fazendo na segunda versão?
info fundo:. Ambos Button
e Button.ClickEvent
são classes públicas não-abstratos
Solução
Classes internas (como Button.ClickEvent
) precisa de uma referência a uma instância da classe externa (Button
).
Essa sintaxe cria uma nova instância de Button.ClickEvent
com o seu exterior conjunto de referência de classe para o valor de button
.
Aqui está um exemplo - ignorar a falta de encapsulamento etc, é apenas para fins de demonstração:
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();
}
}
Consulte seção 8.1.3 da especificação para saber mais sobre classes internas e instâncias que encerram.
Outras dicas
Button.ClickEvent é uma classe interna não-estática para uma instância dessa classe só pode existir fechado em uma instância de Button.
Em seu segundo exemplo de código que você tem uma instância de botão e você criar uma instância de ClickEvent fechado neste caso botão ...
A classe interna não-estática em Java contém uma referência oculto que aponta para uma instância da classe externa é declarada. Então a mensagem de erro que você tem originalmente está lhe dizendo que você não pode criar uma nova instância da classe interna sem especificar também uma instância da classe externa para que possa ser ligado a.
Talvez a razão que você não tenha visto que a sintaxe antes é que classes internas muitas vezes são alocados em um método da classe externa, onde o compilador cuida disso automaticamente.
Para evitar confundir a si mesmo e colegas programadores com este recurso raramente utilizado você sempre pode fazer interno classes estáticas.
No caso de uma referência para a classe externa é necessário você pode passá-lo explicitamente no construtor.
Você realmente pode fazer isso , mas você tem que declarar ClickEvent
como static
Button
dentro, e então você não deve ter qualquer problema com você sintaxe:
buttonClick(new Button.ClickEvent(button));
Basicamente static
torna o ClickEvent
classe pertencem diretamente ao Button
classe em vez de uma instância específica (i. new Button()
) de Button
.
A seguir @ Jon Skeet exemplo:
// 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) {
}
}
Seu código seria compilar, tinha digitado
buttonClick(new Button().ClickEvent(button));
em vez de
buttonClick(new Button.ClickEvent(button));
como um construtor é um método e quando você chamar um método em Java você deve passar a lista de argumentos, mesmo quando ela está vazia.