it-swarm-pt.tech

Classe interna de Java e classe aninhada estática

Qual é a principal diferença entre uma classe interna e uma classe aninhada estática em Java? O design/implementação desempenha um papel na escolha de um deles?

1585
Omnipotent

Do Java Tutorial :

As classes aninhadas são divididas em duas categorias: estática e não estática. Classes aninhadas que são declaradas estáticas são chamadas simplesmente de classes aninhadas estáticas. Classes aninhadas não estáticas são chamadas de classes internas. 

Classes aninhadas estáticas são acessadas usando o nome da classe envolvente:

OuterClass.StaticNestedClass

Por exemplo, para criar um objeto para a classe aninhada estática, use esta sintaxe:

OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();

Objetos que são instâncias de uma classe interna existem dentro de uma instância da classe externa. Considere as seguintes classes:

class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

Uma instância de InnerClass pode existir apenas dentro de uma instância de OuterClass e tem acesso direto aos métodos e campos de sua instância delimitadora.

Para instanciar uma classe interna, você deve primeiro instanciar a classe externa. Em seguida, crie o objeto interno dentro do objeto externo com esta sintaxe:

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

veja: Java Tutorial - Classes Aninhadas

Para completar, note que existe também uma coisa como inner class sem uma instância delimitadora :

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}

Aqui, new A() { ... } é uma classe inner definida em um contexto estático e não possui uma instância delimitadora.

1564
Martin

Eu não acho que a diferença real ficou clara nas respostas acima. 

Primeiro para obter os termos certos: 

  • Uma classe aninhada é uma classe que está contida em outra classe no nível do código-fonte.
  • É estático se você o declarar com o modificador static .
  • Uma classe aninhada não estática é chamada de classe interna. (Eu fico com a classe aninhada não estática.)

A resposta de Martin está certa até agora. No entanto, a pergunta real é: Qual é o propósito de declarar uma classe aninhada estática ou não?

Você usa classes aninhadas estáticas se você quer apenas manter suas classes juntas se elas pertencem topicamente juntas ou se a classe aninhada é usada exclusivamente na classe envolvente. Não há diferença semântica entre uma classe aninhada estática e todas as outras classes.

Classes aninhadas não estáticas são uma besta diferente. Semelhante a classes internas anônimas, essas classes aninhadas são realmente fechamentos. Isso significa que eles capturam seu escopo ao redor e sua instância envolvente e tornam isso acessível. Talvez um exemplo possa esclarecer isso. Veja este stub de um container:

public class Container {
    public class Item{
        Object data;
        public Container getContainer(){
            return Container.this;
        }
        public Item(Object data) {
            super();
            this.data = data;
        }

    }

    public static Item create(Object data){
        // does not compile since no instance of Container is available
        return new Item(data);
    }
    public Item createSubItem(Object data){
        // compiles, since 'this' Container is available
        return new Item(data);
    }
}

Nesse caso, você deseja ter uma referência de um item filho para o contêiner pai. Usando uma classe aninhada não estática, isso funciona sem algum trabalho. Você pode acessar a instância delimitadora do contêiner com a sintaxe Container.this.

Explicações mais explícitas a seguir:

Se você observar os bytecodes Java que o compilador gera para uma classe aninhada (não estática), ela pode se tornar ainda mais clara:

// class version 49.0 (49)
// access flags 33
public class Container$Item {

  // compiled from: Container.Java
  // access flags 1
  public INNERCLASS Container$Item Container Item

  // access flags 0
  Object data

  // access flags 4112
  final Container this$0

  // access flags 1
  public getContainer() : Container
   L0
    LINENUMBER 7 L0
    ALOAD 0: this
    GETFIELD Container$Item.this$0 : Container
    ARETURN
   L1
    LOCALVARIABLE this Container$Item L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 1
  public <init>(Container,Object) : void
   L0
    LINENUMBER 12 L0
    ALOAD 0: this
    ALOAD 1
    PUTFIELD Container$Item.this$0 : Container
   L1
    LINENUMBER 10 L1
    ALOAD 0: this
    INVOKESPECIAL Object.<init>() : void
   L2
    LINENUMBER 11 L2
    ALOAD 0: this
    ALOAD 2: data
    PUTFIELD Container$Item.data : Object
    RETURN
   L3
    LOCALVARIABLE this Container$Item L0 L3 0
    LOCALVARIABLE data Object L0 L3 2
    MAXSTACK = 2
    MAXLOCALS = 3
}

Como você pode ver, o compilador cria um campo oculto Container this$0. Isso é definido no construtor que possui um parâmetro adicional do tipo Container para especificar a instância delimitadora. Você não pode ver este parâmetro na fonte, mas o compilador implicitamente o gera para uma classe aninhada. 

O exemplo de Martin

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

seria assim compilado para uma chamada de algo como (em bytecodes)

new InnerClass(outerObject)

Por uma questão de completude:

Uma classe anônima é um exemplo perfeito de uma classe aninhada não estática que simplesmente não possui um nome associado a ela e não pode ser referenciada posteriormente.

131
jrudolph

Acho que nenhuma das respostas acima explica a diferença real entre uma classe aninhada e uma classe aninhada estática em termos de design de aplicativo: 

Visão global

Uma classe aninhada pode ser não estática ou estática e em cada caso é uma classe definida dentro de outra classe . Uma classe aninhada deve existir apenas para servir é a classe de inclusão , se uma classe aninhada é útil por outras classes (não apenas a inclusão), deve ser declarada como uma classe de nível superior.

Diferença

Classe aninhada não estática : está implicitamente associada à instância delimitadora da classe que contém, isso significa que é possível invocar métodos e acessar variáveis ​​da instância delimitadora. Um uso comum de uma classe aninhada não estática é definir uma classe de adaptador.

Classe aninhada estática : não é possível acessar a instância da classe de inclusão e invocar métodos nela, portanto, deve ser usada quando a classe aninhada não requer acesso a uma instância da classe envolvente. Um uso comum da classe aninhada estática é implementar os componentes do objeto externo.

Conclusão

Portanto, a principal diferença entre os dois a partir de um ponto de vista de design é: classe aninhada não estática pode acessar a instância da classe container, enquanto static não pode.

88
aleroot

Em termos simples, precisamos de classes aninhadas principalmente porque o Java não fornece closures.

Classes Aninhadas são classes definidas dentro do corpo de outra classe envolvente. Eles são de dois tipos - estáticos e não estáticos.

Eles são tratados como membros da classe envolvente, portanto, você pode especificar qualquer um dos quatro especificadores de acesso - private, package, protected, public. Não temos esse luxo com classes de nível superior, que só podem ser declaradas como public ou package-private.

Classes internas, também conhecidas como classes Não-empilhamento, têm acesso a outros membros da classe superior, mesmo que sejam declaradas como privadas, enquanto as classes estáticas aninhadas não têm acesso a outros membros da classe superior.

public class OuterClass {
    public static class Inner1 {
    }
    public class Inner2 {
    }
}

Inner1 é nossa classe interna estática e Inner2 é nossa classe interna que não é estática. A principal diferença entre eles é que você não pode criar uma instância Inner2 sem um Outer onde você pode criar um objeto Inner1 independentemente.

Quando você usaria a classe Inner?

Pense em uma situação em que Class A e Class B estão relacionados, Class B precisa acessar Class A membros e Class B está relacionado apenas a Class A. As aulas internas entram em cena.

Para criar uma instância de classe interna, você precisa criar uma instância de sua classe externa.

OuterClass outer = new OuterClass();
OuterClass.Inner2 inner = outer.new Inner2();

ou

OuterClass.Inner2 inner = new OuterClass().new Inner2();

Quando você usaria classe interna estática?

Você definiria uma classe interna estática quando souber que ela não tem relação com a instância da classe class/top anexa. Se a sua classe interna não usa métodos ou campos da classe externa, é apenas um desperdício de espaço, então torne-a estática.

Por exemplo, para criar um objeto para a classe aninhada estática, use esta sintaxe:

OuterClass.Inner1 nestedObject = new OuterClass.Inner1();

A vantagem de uma classe aninhada estática é que ela não precisa que um objeto da classe/classe superior contida funcione. Isso pode ajudá-lo a reduzir o número de objetos que seu aplicativo cria em tempo de execução.

31
Thalaivar

Eu acho que a convenção que geralmente é seguida é esta:

  • classe estática dentro de uma classe de nível superior é uma classe aninhada
  • classe não estática dentro de uma classe de nível superior é uma classe interna , que ainda tem mais duas formas:
    • classe local - classes nomeadas declaradas dentro de um bloco como um método ou corpo de construtor
    • classe anônima - classes sem nome cujas instâncias são criadas em expressões e declarações

No entanto, alguns outros pontos para lembrar são:

  • As classes de nível superior e a classe aninhada estática são semanticamente iguais, exceto que, no caso de classe aninhada estática, ela pode fazer referência estática a campos/métodos estáticos privados de sua classe Outer [parent] e vice-versa.

  • Classes internas têm acesso a variáveis ​​de instância da instância delimitadora da classe Outer [parent]. No entanto, nem todas as classes internas possuem instâncias delimitadoras, por exemplo, classes internas em contextos estáticos, como uma classe anônima usada em um bloco inicializador estático, não.

  • Por padrão, a classe anônima estende a classe pai ou implementa a interface pai e não há nenhuma cláusula adicional para estender qualquer outra classe ou implementar mais interfaces. Assim,

    • new YourClass(){}; significa class [Anonymous] extends YourClass {}
    • new YourInterface(){}; significa class [Anonymous] implements YourInterface {}

Eu sinto que a grande questão que permanece em aberto é qual usar e quando? Bem, isso depende principalmente de qual cenário você está lidando, mas ler a resposta dada por @jrudolph pode ajudá-lo a tomar alguma decisão.

26
sactiw

Aqui estão as principais diferenças e semelhanças entre a classe interna Java e a classe aninhada estática.

Espero que ajude!

Classe interna

  • Pode acessar para a classe externa instâncias e estáticas métodos e campos
  • Associado à instância de inclusão da classe para instanciar primeiro precisa de uma instância da classe externa (note new local da palavra-chave):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
    
  • Cannot define any membros estáticos propriamente dito

  • Não pode ter Class ou Interface declaração

Classe aninhada estática

  • Não é possível acessar classe externa instância métodos ou campos

  • Não associado a nenhuma instância de classe envolvente Então, para instanciá-lo:

    OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
    

Semelhanças

  • Ambas classes internas podem acessar até campos e métodos privados de classe externa
  • Também o Outer class tem acesso a campos e métodos privados de classes internas
  • Ambas as classes podem ter modificador de acesso privado, protegido ou público

Por que usar classes aninhadas?

De acordo com a documentação da Oracle, existem vários motivos ( documentação completa ):

  • É uma maneira de agrupar logicamente classes que são usadas somente em um lugar: Se uma classe é útil para apenas uma outra classe, então é lógico embuti-la nessa classe e manter os dois juntos. Aninhar essas "classes auxiliares" torna seu pacote mais simplificado.

  • Aumenta o encapsulamento: Considere duas classes de nível superior, A e B, em que B precisa de acesso a membros de A que, de outro modo, seriam declarados como privados. Ao ocultar a classe B dentro da classe A, os membros de A podem ser declarados privados e B pode acessá-los. Além disso, o próprio B pode ser escondido do mundo exterior.

  • Pode levar a código mais legível e de fácil manutenção: Aninhar pequenas classes dentro de classes de nível superior coloca o código mais próximo de onde ele é usado.

26
Behzad Bahmanyar

Classe aninhada: classe dentro da classe

Tipos:

  1. Classe aninhada estática
  2. Classe aninhada não estática [classe interna]

Diferença:

Classe aninhada não estática [Classe interna]

No objeto de classe aninhada não estático da classe interna existe dentro do objeto da classe externa. Assim, esse membro de dados da classe externa é acessível para a classe interna. Então, para criar um objeto de classe interna, devemos criar primeiro o objeto da classe externa.

outerclass outerobject=new outerobject();
outerclass.innerclass innerobjcet=outerobject.new innerclass(); 

Classe aninhada estática

No objeto de classe aninhada estático da classe interna não é necessário o objeto da classe externa, porque a palavra "estática" não indica a necessidade de criar um objeto.

class outerclass A {
    static class nestedclass B {
        static int x = 10;
    }
}

Se você quiser acessar x, escreva o seguinte método interno

  outerclass.nestedclass.x;  i.e. System.out.prinltn( outerclass.nestedclass.x);
15
tejas

Há uma sutileza sobre o uso de classes estáticas aninhadas que podem ser úteis em determinadas situações.

Enquanto atributos estáticos são instanciados antes que a classe seja instanciada via seu construtor, Atributos estáticos dentro de classes estáticas aninhadas não parecem ser instanciados até que o construtor da classe Seja invocado, ou pelo menos não até que os atributos sejam referenciados pela primeira vez, , mesmo que estejam marcados como 'final'.

Considere este exemplo:

public class C0 {

    static C0 instance = null;

    // Uncomment the following line and a null pointer exception will be
    // generated before anything gets printed.
    //public static final String outerItem = instance.makeString(98.6);

    public C0() {
        instance = this;
    }

    public String makeString(int i) {
        return ((new Integer(i)).toString());
    }

    public String makeString(double d) {
        return ((new Double(d)).toString());
    }

    public static final class nested {
        public static final String innerItem = instance.makeString(42);
    }

    static public void main(String[] argv) {
        System.out.println("start");
        // Comment out this line and a null pointer exception will be
        // generated after "start" prints and before the following
        // try/catch block even gets entered.
        new C0();
        try {
            System.out.println("retrieve item: " + nested.innerItem);
        }
        catch (Exception e) {
            System.out.println("failed to retrieve item: " + e.toString());
        }
        System.out.println("finish");
    }
}

Mesmo que 'aninhado' e 'innerItem' sejam declarados como 'final estático'. a configuração de nested.innerItem não ocorre até que a classe seja instanciada (ou pelo menos não até que o item estático aninhado seja mencionado pela primeira vez), como você pode ver por si mesmo comentando e descomentando as linhas a que me refiro acima. O mesmo não vale Verdadeiro para 'outerItem'.

Pelo menos é isso que estou vendo no Java 6.0.

11
HippoMan

A instância da classe interna é criada quando a instância da classe externa é criada. Portanto, os membros e métodos da classe interna têm acesso aos membros e métodos da instância (objeto) da classe externa. Quando a instância da classe externa sai do escopo, também as instâncias da classe interna deixam de existir.

A classe aninhada estática não tem uma instância concreta. É apenas carregado quando é usado pela primeira vez (assim como os métodos estáticos). É uma entidade completamente independente, cujos métodos e variáveis ​​não têm acesso às instâncias da classe externa.

As classes aninhadas estáticas não são acopladas ao objeto externo, são mais rápidas e não recebem memória de heap/pilha, porque não é necessário criar uma instância dessa classe. Portanto, a regra básica é tentar definir uma classe aninhada estática, com o escopo limitado possível (private> = class> = protected> = public) e, em seguida, convertê-la em classe interna (removendo o identificador "estático") e soltar o escopo, se é realmente necessário.

11
rmaruszewski

Eu não acho que há muito a acrescentar aqui, a maioria das respostas explica perfeitamente as diferenças entre a classe aninhada estática e as classes internas. No entanto, considere o seguinte problema ao usar classes aninhadas versus classes internas. Como mencionado em algumas respostas, as classes internas não podem ser instanciadas sem uma instância de sua classe envolvente, o que significa que elasHOLDa pointer para a instância de sua classe envolvente que pode levar a um estouro de memória ou a uma exceção de estouro de pilha devido ao fato de que o GC não conseguirá coletar lixo nas classes envolvidas, mesmo que elas não sejam mais usadas. Para tornar isso claro, verifique o seguinte código: 

public class Outer {


    public  class Inner {

    }


    public Inner inner(){
        return new Inner();
    }

    @Override
    protected void finalize() throws Throwable {
    // as you know finalize is called by the garbage collector due to destroying an object instance
        System.out.println("I am destroyed !");
    }
}


public static void main(String arg[]) {

    Outer outer = new Outer();
    Outer.Inner inner = outer.new Inner();

    // out instance is no more used and should be garbage collected !!!
    // However this will not happen as inner instance is still alive i.e used, not null !
    // and outer will be kept in memory until inner is destroyed
    outer = null;

    //
    // inner = null;

    //kick out garbage collector
    System.gc();

}

Se você remover o comentário sobre // inner = null; O programa irá colocar " Eu estou destruído! ", mas mantendo isso comentado, não.
O motivo é que a instância interna branca ainda é referenciada. A GC não pode coletá-la e, como faz referência (tem um ponteiro para) a instância externa, ela não é coletada também. Tendo bastante desses objetos em seu projeto e pode ficar sem memória.
Comparado a classes internas estáticas que não mantêm um ponto para a instância da classe interna porque não é relacionado à instância, mas sim relacionado à classe. O programa acima pode imprimir " Estou destruído! " se você tornar a classe Inner estática e instanciada com Outer.Inner i = new Outer.Inner(); 

10
Adelin

No caso de criar instância, a instância da classe interna estática não É criada com a referência do objeto Da classe externa na qual ela está definida. Isto Significa que tem instância inclinada. Mas o exemplo da classe interna estática É criado com a referência da classe Outer, não com A referência do objeto de classe externa. Isso significa que Não tem instância de inclusão.

Por exemplo:

class A
{
  class B
  {
    // static int x; not allowed here…..    
  }
  static class C
  {
    static int x; // allowed here
  }
}

class Test
{
  public static void main(String… str)
  {
    A o=new A();
    A.B obj1 =o.new B();//need of inclosing instance

    A.C obj2 =new A.C();

    // not need of reference of object of outer class….
  }
}
10
Ankit Jain

Os termos são usados ​​de forma intercambiável. Se você quer ser realmente pedante sobre isso, então você poderia define "classe aninhada" para se referir a uma classe interna estática, uma que não possui nenhuma instância delimitadora. No código, você pode ter algo assim:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

Isso não é realmente uma definição amplamente aceita.

8
Daniel Spiewak

A classe aninhada é um termo muito geral: toda classe que não é de nível superior é uma classe aninhada. Uma classe interna é uma classe aninhada não estática. Joseph Darcy escreveu uma explicação muito boa sobre Classes aninhadas, internas, membros e de nível superior .

8
Wouter Coekaerts

Targeting learner, que são novatos em Java e/ou em classes aninhadas 

As classes aninhadas podem ser:
1. Classes Estáticas Aninhadas.
2. Classes aninhadas não estáticas. (também conhecido como Classes internas ) => Por favor, lembre-se disto


1.Aulas internas
Exemplo:

class OuterClass  {
/*  some code here...*/
     class InnerClass  {  }
/*  some code here...*/
}


Classes internas são subconjuntos de classes aninhadas:

  • classe interna é um tipo específico de classe aninhada
  • classes internas são subconjuntos de classes aninhadas
  • Você pode dizer que uma classe interna também é uma classe aninhada, mas você podeN&ATILDE;Odizer que uma classe aninhada também é uma classe interna

Especialidade da classe interna:

  • exemplo de uma classe interna tem acesso a todos dos membros da classe externa, mesmo aqueles que estão marcados como "privados"


2. Classes Estáticas Aninhadas:
Exemplo:

class EnclosingClass {
  static class Nested {
    void someMethod() { System.out.println("hello SO"); }
  }
}

Caso 1: instanciando uma classe aninhada estática de uma classe não inclusiva

class NonEnclosingClass {

  public static void main(String[] args) {
    /*instantiate the Nested class that is a static
      member of the EnclosingClass class:
    */

    EnclosingClass.Nested n = new EnclosingClass.Nested(); 
    n.someMethod();  //prints out "hello"
  }
}

Caso 2: instanciando uma classe aninhada estática de uma classe de inclusão

class EnclosingClass {

  static class Nested {
    void anotherMethod() { System.out.println("hi again"); } 
  }

  public static void main(String[] args) {
    //access enclosed class:

    Nested n = new Nested(); 
    n.anotherMethod();  //prints out "hi again"
  }

}

Especialidade de classes estáticas:

  • A classe interna estática só teria acesso aos membros estáticos da classe externa e não teria acesso a membros não estáticos.

Conclusão:
Question: Qual é a principal diferença entre uma classe interna e uma classe aninhada estática em Java?
Answer: apenas passe por detalhes de cada classe mencionada acima.

7
VdeX

Ummm ... uma classe interna IS uma classe aninhada ... você quer dizer classe anônima e classe interna?

Edit: Se você realmente quis dizer interna vs anônima ... uma classe interna é apenas uma classe definida dentro de uma classe como:

public class A {
    public class B {
    }
}

Considerando que uma classe anônima é uma extensão de uma classe definida anonimamente, então nenhuma classe real é definida, como em:

public class A {
}

A anon = new A() { /* you could change behavior of A here */ };

Edição adicional:

Wikipedia afirma que há uma diferença em Java, mas eu tenho trabalhado com Java por 8 anos, e é o primeiro que ouvi tal distinção ... para não mencionar que não há referências lá para fazer backup do pedido ... linha inferior, uma classe interna é uma classe definida dentro de uma classe (estática ou não), e aninhada é apenas outro termo para significar a mesma coisa.

Há uma diferença sutil entre classes aninhadas estáticas e não estáticas ... Basicamente, classes internas não-estáticas têm acesso implícito a campos de instância e métodos da classe envolvente (assim eles não podem ser construídos em um contexto estático, ele será um compilador erro). As classes aninhadas estáticas, por outro lado, não têm acesso implícito a campos e métodos de instância e podem ser construídas em um contexto estático.

7
Mike Stone

Classe interna e classe estática aninhada em Java ambas são classes declaradas dentro de outra classe, conhecida como classe de nível superior em Java. Na terminologia Java, se você declarar uma classe aninhada estática, ela será chamada de classe estática aninhada em Java, enquanto que as classes aninhadas não estáticas são simplesmente chamadas de Classe Interna. 

O que é classe interna em Java?

Qualquer classe que não seja de nível superior ou declarada dentro de outra classe é conhecida como classe aninhada e fora dessas classes aninhadas, as classes que são declaradas não estáticas são conhecidas como classe interna em Java. Existem três tipos de classe interna em Java:

1) Classe interna local - é declarada dentro de um bloco de código ou método.
2) Anonymous inner class - é uma classe que não tem nome para referenciar e inicializada no mesmo lugar onde é criada.
3) Classe interna do membro - é declarada como membro não estático da classe externa.

public class InnerClassTest {
    public static void main(String args[]) {      
        //creating local inner class inside method i.e. main() 
        class Local {
            public void name() {
                System.out.println("Example of Local class in Java");

            }
        }      
        //creating instance of local inner class
        Local local = new Local();
        local.name(); //calling method from local inner class

        //Creating anonymous inner class in Java for implementing thread
        Thread anonymous = new Thread(){
            @Override
            public void run(){
                System.out.println("Anonymous class example in Java");
            }
        };
        anonymous.start();

        //example of creating instance of inner class
        InnerClassTest test = new InnerClassTest();
        InnerClassTest.Inner inner = test.new Inner();
        inner.name(); //calling method of inner class
    }

     //Creating Inner class in Java
    private class Inner{
        public void name(){
            System.out.println("Inner class example in Java");
        }
    }
}

O que é uma classe estática aninhada em Java?

A classe estática aninhada é outra classe que é declarada dentro de uma classe como membro e tornada estática. A classe estática aninhada também é declarada como membro da classe externa e pode tornar-se privada, pública ou protegida como qualquer outro membro. Um dos principais benefícios da classe estática aninhada sobre a classe interna é que a instância da classe estática aninhada não é anexada a nenhuma instância delimitadora da classe Outer. Você também não precisa de nenhuma instância da classe Outer para criar uma instância da classe estática aninhada em Java.

1) Pode acessar membros de dados estáticos da classe externa, incluindo privado.
2) A classe aninhada estática não pode acessar membro de dados não estático (instância) ou método.

public class NestedStaticExample {
    public static void main(String args[]){  
        StaticNested nested = new StaticNested();
        nested.name();
    }  
    //static nested class in Java
    private static class StaticNested{
        public void name(){
            System.out.println("static nested class example in Java");
        }
    }
}

Ref: Classe interna e classe estática aninhada em Java com exemplo

6
roottraveller

Quando declaramos classe de membro estático dentro de uma classe, ela é conhecida como classe aninhada de nível superior ou uma classe aninhada estática. Pode ser demonstrado como abaixo: 

class Test{
    private static int x = 1;
        static class A{
        private static int y = 2;
        public static int getZ(){
            return B.z+x;
        }
    }
    static class B{
        private static int z = 3;
        public static int getY(){
            return A.y;
        }
    }
}

class TestDemo{
     public static void main(String[] args){
        Test t = new Test();
        System.out.println(Test.A.getZ());
        System.out.println(Test.B.getY());
    }
}

Quando declaramos classe de membro não estático dentro de uma classe, ela é conhecida como classe interna. A classe interna pode ser demonstrada como abaixo: 

    class Test{
        private int i = 10;
        class A{
            private int i =20;
            void display(){
            int i = 30;
            System.out.println(i);
            System.out.println(this.i);
            System.out.println(Test.this.i);
        }
    }
}
5
Pankti

Eu acho que as pessoas aqui deveriam notar para Poster que: Static Nest Class apenas apenas a primeira classe interna. Por exemplo:

 public static class A {} //ERROR

 public class A {
     public class B {
         public static class C {} //ERROR
     }
 }

 public class A {
     public static class B {} //COMPILE !!!

 }

Resumindo, a classe estática não depende de qual classe ela contém. Então, eles não podem na aula normal. (porque a classe normal precisa de uma instância).

5
hqt

O seguinte é um exemplo de static nested class e inner class:

OuterClass.Java

public class OuterClass {
     private String someVariable = "Non Static";

     private static String anotherStaticVariable = "Static";  

     OuterClass(){

     }

     //Nested classes are static
     static class StaticNestedClass{
        private static String privateStaticNestedClassVariable = "Private Static Nested Class Variable"; 

        //can access private variables declared in the outer class
        public static void getPrivateVariableofOuterClass(){
            System.out.println(anotherStaticVariable);
        }
     }

     //non static
     class InnerClass{

         //can access private variables of outer class
         public String getPrivateNonStaticVariableOfOuterClass(){
             return someVariable;
         }
     }

     public static void accessStaticClass(){
         //can access any variable declared inside the Static Nested Class 
         //even if it private
         String var = OuterClass.StaticNestedClass.privateStaticNestedClassVariable; 
         System.out.println(var);
     }

}

OuterClassTest:

public class OuterClassTest {
    public static void main(String[] args) {

        //access the Static Nested Class
        OuterClass.StaticNestedClass.getPrivateVariableofOuterClass();

        //test the private variable declared inside the static nested class
        OuterClass.accessStaticClass();
        /*
         * Inner Class Test
         * */

        //Declaration

        //first instantiate the outer class
        OuterClass outerClass = new OuterClass();

        //then instantiate the inner class
        OuterClass.InnerClass innerClassExample =  outerClass. new InnerClass();

        //test the non static private variable
        System.out.println(innerClassExample.getPrivateNonStaticVariableOfOuterClass()); 

    }

}
3
Pritam Banerjee

Eu acho que nenhuma das respostas acima dar o exemplo real para você a diferença entre uma classe aninhada e uma classe aninhada estática em termos de design do aplicativo. E a principal diferença entre a classe aninhada estática e a classe interna é a capacidade de acessar o campo da instância da classe externa.

Vamos dar uma olhada nos dois exemplos a seguir.

Classe de aninhamento estático: Um bom exemplo de uso de classes aninhadas estáticas é o padrão de construtor ( https://dzone.com/articles/design-patterns-the-builder-pattern ).

Para BankAccount usamos uma classe aninhada estática, principalmente porque

  1. A instância de classe aninhada estática pode ser criada antes da classe externa.

  2. No padrão do construtor, o construtor é uma classe auxiliar usada para criar o BankAccount.

  3. O BankAccount.Builder é associado apenas ao BankAccount. Nenhuma outra classe está relacionada ao BankAccount.Builder. Por isso, é melhor organizá-los juntos sem usar a convenção de nomes.
public class BankAccount {

    private long accountNumber;
    private String owner;
    ...

    public static class Builder {

    private long accountNumber;
    private String owner;
    ...

    static public Builder(long accountNumber) {
        this.accountNumber = accountNumber;
    }

    public Builder withOwner(String owner){
        this.owner = owner;
        return this; 
    }

    ...
    public BankAccount build(){
            BankAccount account = new BankAccount(); 
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            ...
            return account;
        }
    }
}

Classe interna: Um uso comum de classes internas é definir um manipulador de eventos. https://docs.Oracle.com/javase/tutorial/uiswing/events/generalrules.html

Para MyClass, usamos a classe interna, principalmente porque:

  1. A classe interna MyAdapter precisa acessar o membro da classe externa.

  2. No exemplo, o MyAdapter é associado apenas ao MyClass. Nenhuma outra classe está relacionada ao MyAdapter. por isso é melhor organizá-los juntos sem usar uma convenção de nome

public class MyClass extends Applet {
    ...
        someObject.addMouseListener(new MyAdapter());
    ...
    class MyAdapter extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            ...// Event listener implementation goes here...
            ...// change some outer class instance property depend on the event
        }
    }
}
1
Leogao

A linguagem de programação Java permite que você defina uma classe dentro de outra classe. Essa classe é chamada de uma classe aninhada e é ilustrada aqui:

class OuterClass {
...
class NestedClass {
    ...
    }
}

As classes aninhadas são divididas em duas categorias: estática e não estática. Classes aninhadas que são declaradas estáticas são chamadas de classes aninhadas estáticas. Classes aninhadas não-estáticas são chamadas de classes internas. Uma coisa que devemos ter em mente é que classes aninhadas não-estáticas (classes internas) têm acesso a outros membros da classe envolvente, mesmo que sejam declaradas privadas. As classes aninhadas estáticas só têm acesso a outros membros da classe incluída, se essas forem estáticas. Ele não pode acessar membros não estáticos da classe externa. Como com métodos e variáveis ​​de classe, uma classe aninhada estática é associada à sua classe externa. Por exemplo, para criar um objeto para a classe aninhada estática, use esta sintaxe:

OuterClass.StaticNestedClass nestedObject =
 new OuterClass.StaticNestedClass(); 

Para instanciar uma classe interna, você deve primeiro instanciar a classe externa. Em seguida, crie o objeto interno dentro do objeto externo com esta sintaxe:

OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

Por que usamos classes aninhadas

  1. É uma maneira de agrupar logicamente classes que são usadas apenas em um lugar.
  2. Aumenta o encapsulamento.
  3. Isso pode levar a um código mais legível e sustentável.

Fonte: Tutoriais Java ™ - Classes aninhadas

0
Mithun Debnath

Primeiro de tudo Não existe tal classe chamada Static class. O modificador Static use com inner class (chamado de Nested Class) diz que é um membro estático de Outer Class, o que significa que podemos acessá-lo como com outros membros estáticos e sem ter qualquer instância da classe Outer. (Que é o benefício da estática originalmente.) 

A diferença entre usar a classe aninhada e a classe interna regular é:

OuterClass.InnerClass inner = new OuterClass().new InnerClass();

Primeiro podemos instanciar Outerclass então podemos acessar Inner.

Mas se a classe estiver aninhada, a sintaxe será:

OuterClass.InnerClass inner = new OuterClass.InnerClass();

Que usa a sintaxe estática como implementação normal da palavra-chave estática.

0
Sohi