Classe interna Java e classe aninhada estática

1766

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?

Onipotente
fonte
65
A resposta de Joshua Bloch está em Effective Java ler item 22 : Favor static member classes over non static
Raymond Chenon
4
Para constar, é o item 24 da 3ª edição do mesmo livro.
ZeroCool

Respostas:

1696

No Tutorial Java :

Classes aninhadas são divididas em duas categorias: estática e não estática. Classes aninhadas 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 anexa:

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 do InnerClass pode existir apenas dentro de uma instância do OuterClass e tem acesso direto aos métodos e campos de sua instância anexa.

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 outerObject = new OuterClass()
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

consulte: Tutorial Java - Classes aninhadas

Para completar, observe que também existe uma classe interna sem uma instância anexa :

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

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

Martin
fonte
130
Mente que você também pode importar uma classe aninhada estática diretamente, ou seja, você poderia fazer (na parte superior do arquivo): import OuterClass.StaticNestedClass; seguida, fazer referência a classe apenas como OuterClass.
Camilo Díaz Repka
4
@ Martin existe algum nome técnico específico para esse idioma de criação de uma classe interna OuterClass.InnerClass innerObject = outerObject.new InnerClass();?
28413 Geek
7
Então, qual é o uso da classe aninhada estática privada? Eu acho que não podemos instanciar do lado de fora como OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass ();
RoboAlex
1
@Ilya Kogan: Eu quis dizer que sei que podemos acessar os campos de classe dos pais, estáticos ou não estáticos (se a classe filho for uma classe não estática), eu usei seus recursos algumas vezes, mas eu queria saber que tipo de modelo de memória. eles seguem? os conceitos de POO os cobrem como um conceito separado? se não onde eles realmente se encaixam no OOP. Parece que uma classe amigo para me :)
Mubashar
4
@martin, eu sei que estou chegando a esse segmento incrivelmente tarde, mas: é sua variável, a, que é um campo estático da classe A. Isso não significa que a classe anônima criada por 'new A () {int t () {retorno 2; }} 'é estático, assim como se eu simplesmente atribuísse qualquer outro objeto ao campo estático, a, como em: class B {static void main (string s) {Aa = new A ()}} (A & B no mesmo pacote) Isso não torna A uma classe estática. A frase "contexto estático", na referência citada no tópico ao qual você vinculou, é incrivelmente vaga. De fato, isso foi observado em muitos dos comentários desse segmento.
GrantRobertson
599

O tutorial Java diz :

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

Na linguagem comum, os termos "aninhado" e "interno" são usados ​​de forma intercambiável pela maioria dos programadores, mas usarei o termo correto "classe aninhada", que abrange interno e estático.

As classes podem ser aninhadas ad infinitum , por exemplo, a classe A pode conter a classe B, que contém a classe C, que contém a classe D, etc. No entanto, mais de um nível de aninhamento de classe é raro, pois geralmente é um design ruim.

Há três razões para você criar uma classe aninhada:

  • organização: às vezes parece mais sensato classificar uma classe no espaço para nome de outra classe, especialmente quando ela não será usada em nenhum outro contexto
  • acesso: classes aninhadas têm acesso especial às variáveis ​​/ campos de suas classes contidas (precisamente quais variáveis ​​/ campos dependem do tipo de classe aninhada, seja interna ou estática).
  • conveniência: ter que criar um novo arquivo para cada novo tipo é incômodo, novamente, especialmente quando o tipo será usado apenas em um contexto

Existem quatro tipos de classe aninhada em Java . Em resumo, são eles:

  • classe estática : declarada como membro estático de outra classe
  • classe interna : declarada como um membro da instância de outra classe
  • classe interna local : declarada dentro de um método de instância de outra classe
  • classe interna anônima : como uma classe interna local, mas escrita como uma expressão que retorna um objeto único

Deixe-me elaborar em mais detalhes.


Classes estáticas

Classes estáticas são o tipo mais fácil de entender porque não têm nada a ver com instâncias da classe que os contém.

Uma classe estática é uma classe declarada como um membro estático de outra classe. Assim como outros membros estáticos, essa classe é realmente apenas um cabide que usa a classe que contém como espaço para nome, por exemplo , a classe Goat declarada como membro estático da classe Rhino no pacote pizza é conhecida pelo nome pizza.Rhino.Goat .

package pizza;

public class Rhino {

    ...

    public static class Goat {
        ...
    }
}

Francamente, classes estáticas são um recurso inútil, porque as classes já estão divididas em namespaces por pacotes. A única razão real concebível para criar uma classe estática é que essa classe tem acesso aos membros estáticos privados da classe que a contém, mas acho que essa é uma justificativa bastante fraca para o recurso de classe estática.


Classes internas

Uma classe interna é uma classe declarada como um membro não estático de outra classe:

package pizza;

public class Rhino {

    public class Goat {
        ...
    }

    private void jerry() {
        Goat g = new Goat();
    }
}

Como em uma classe estática, a classe interna é conhecida como qualificada pelo nome da classe que contém, pizza.Rhino.Goat , mas dentro da classe que contém, ela pode ser conhecida pelo nome simples. No entanto, toda instância de uma classe interna está vinculada a uma instância específica de sua classe que contém: acima, o Goat criado em jerry , está implicitamente vinculado à instância do Rhino que está em jerry . Caso contrário, tornamos explícita a instância associada do Rhino quando instanciamos o Goat :

Rhino rhino = new Rhino();
Rhino.Goat goat = rhino.new Goat();

(Observe que você se refere ao tipo interno como apenas Goat na nova e estranha sintaxe: Java infere o tipo que contém a parte rhino . E sim, o novo rhino.Goat () também faria mais sentido para mim.)

Então, o que isso nos ganha? Bem, a instância da classe interna tem acesso aos membros da instância da classe que o contém. Estes membros de instância envolvente são referidos dentro da classe interna através de apenas os seus nomes simples, não via este ( esta na classe interna refere-se à ocorrência de classe interior, não contendo a instância de classe associado):

public class Rhino {

    private String barry;

    public class Goat {
        public void colin() {
            System.out.println(barry);
        }
    }
}

Na classe interna, você pode se referir a isso da classe que contém como Rhino.this e pode usar isso para se referir a seus membros, por exemplo , Rhino.this.barry .


Classes internas locais

Uma classe interna local é uma classe declarada no corpo de um método. Essa classe é conhecida apenas em seu método de contenção; portanto, ela só pode ser instanciada e ter seus membros acessados ​​em seu método de contenção. O ganho é que uma instância local da classe interna está vinculada e pode acessar as variáveis ​​locais finais do seu método que o contém. Quando a instância usa um local final do método que a contém, a variável retém o valor que ela mantinha no momento da criação da instância, mesmo que a variável tenha saído do escopo (essa é efetivamente a versão bruta e limitada de fechamentos de Java).

Como uma classe interna local não é membro de uma classe ou pacote, ela não é declarada com um nível de acesso. (Seja claro, no entanto, que seus próprios membros têm níveis de acesso como em uma classe normal.)

Se uma classe interna local é declarada em um método de instância, uma instanciação da classe interna é vinculada à instância mantida pelos métodos contendo isso no momento da criação da instância e, portanto, os membros da instância da classe que estão contidos são acessíveis como em uma instância classe interna. Uma classe interna local é instanciada simplesmente por seu nome, por exemplo , a classe interna local Cat é instanciada como nova Cat () , não nova this.Cat () como você poderia esperar.


Classes internas anônimas

Uma classe interna anônima é uma maneira sintaticamente conveniente de escrever uma classe interna local. Geralmente, uma classe interna local é instanciada no máximo apenas uma vez cada vez que seu método de contenção é executado. Seria bom, então, se pudéssemos combinar a definição de classe interna local e sua instanciação única em uma forma de sintaxe conveniente, e também seria bom se não tivéssemos que criar um nome para a classe (quanto menos inútil nomes que seu código contém, melhor). Uma classe interna anônima permite essas duas coisas:

new *ParentClassName*(*constructorArgs*) {*members*}

Esta é uma expressão retornando uma nova instância de uma classe sem nome que estende ParentClassName . Você não pode fornecer seu próprio construtor; ao contrário, é fornecido um implicitamente que simplesmente chama o super construtor, de modo que os argumentos fornecidos devem se encaixar no super construtor. (Se o pai contém vários construtores, o “mais simples” é chamado de “mais simples”, conforme determinado por um conjunto bastante complexo de regras que não vale a pena se preocupar em aprender em detalhes - basta prestar atenção ao que o NetBeans ou o Eclipse lhe dizem.)

Como alternativa, você pode especificar uma interface para implementar:

new *InterfaceName*() {*members*}

Essa declaração cria uma nova instância de uma classe sem nome que estende Object e implementa InterfaceName . Novamente, você não pode fornecer seu próprio construtor; nesse caso, o Java fornece implicitamente um construtor sem argumento, não faça nada (portanto, nunca haverá argumentos construtores nesse caso).

Mesmo que você não possa atribuir a uma classe interna anônima um construtor, você ainda pode fazer qualquer configuração desejada usando um bloco inicializador (um bloco {} colocado fora de qualquer método).

Seja claro que uma classe interna anônima é simplesmente uma maneira menos flexível de criar uma classe interna local com uma instância. Se você deseja uma classe interna local que implementa várias interfaces ou que implementa interfaces enquanto estende alguma classe que não seja Object ou especifica seu próprio construtor, você está impedido de criar uma classe interna local nomeada regular.

Jegschemesch
fonte
39
Ótima história, obrigado. Mas há um erro. Você pode acessar os campos de uma classe externa a partir de uma classe interna da instância por Rhino.this.variableName.
Thirler 30/07/09
2
Embora não seja possível fornecer seu próprio construtor para classes internas anônimas, você pode usar a inicialização entre chaves. c2.com/cgi/wiki?DoubleBraceInitialization
Casebash
30
Ótima explicação, mas não concordo que as classes internas estáticas sejam inúteis. Consulte rwhansen.blogspot.com/2007/07/… para obter uma grande variação do padrão do construtor que depende muito do uso de classes internas estáticas.
Mansoor Siddiqui
9
Também discordo que a classe interna estática é inútil: se você quiser uma enumeração na classe interna, precisará tornar a classe interna estática.
Alguém em algum lugar
9
Classes aninhadas estáticas privadas também são bastante úteis: você deseja tê-las, mas não deseja expô-las. Como entrada <T> em um LinkedList <T>, ou AsyncTasks dentro de uma Atividade (Android), etc ...
Lorenzo DEMATTÊ
150

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

Primeiro, para acertar os termos:

  • 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 estático .
  • Uma classe aninhada não estática é chamada de classe interna. (Eu permaneço com a classe aninhada não estática.)

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

Você usa classes aninhadas estáticas se desejar apenas manter suas classes unidas se pertencerem topicamente juntas ou se a classe aninhada for 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 um animal diferente. Semelhante às classes internas anônimas, essas classes aninhadas são na verdade encerramentos. Isso significa que eles capturam seu escopo circundante e sua instância anexa e o tornam acessível. Talvez um exemplo esclareça isso. Veja este esboço de um contêiner:

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 anexa do Container 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), pode ficar ainda mais claro:

// 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 anexa. Você não pode ver esse parâmetro na fonte, mas o compilador o gera implicitamente 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 tem nome associado a ela e não pode ser referenciada posteriormente.

jrudolph
fonte
17
"Não há diferença semântica entre uma classe aninhada estática e todas as outras classes." Exceto que a classe aninhada pode ver os campos / métodos privados do pai e a classe pai pode ver os campos / métodos privados do pai.
Brad Cupit
A classe interna não estática não causaria um vazamento maciço de memória? Toda vez que você cria um ouvinte, você cria um vazamento?
GDV
3
@ G_V definitivamente existe um potencial de vazamento de memória porque uma instância da classe interna mantém uma referência à classe externa. Se este é um problema real, depende de onde e como as referências a instâncias das classes externa e interna são mantidas.
Jrudolph
94

Penso que nenhuma das respostas acima explica a diferença real entre uma classe aninhada e uma classe aninhada estática no termo do design do aplicativo:

Visão geral

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

Diferença

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

Classe aninhada estática : não pode acessar a instância da classe anexa e invocar métodos nela; portanto, deve ser usado quando a classe aninhada não exigir acesso a uma instância da classe anexa. Um uso comum da classe aninhada estática é implementar componentes do objeto externo.

Conclusão

Portanto, a principal diferença entre os dois do ponto de vista do design é: a classe aninhada não estática pode acessar a instância da classe de contêiner, enquanto a estática não .

aleroot
fonte
: da sua conclusão "enquanto estática não pode", nem mesmo instâncias estáticas do contêiner? Certo?
VdeX 21/07
Um uso comum da classe aninhada estática é o padrão de design do ViewHolder no RecyclerView e no ListView.
Hamzeh Soboh
1
Em muitos casos, a resposta curta é mais clara e melhor. Este é um exemplo.
Eric Wang
32

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

Classes aninhadas são classes definidas dentro do corpo de outra classe anexa. 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 publicou privadas de pacotes.

Classes internas, também conhecidas como classes sem pilha, têm acesso a outros membros da classe superior, mesmo que sejam declaradas privadas enquanto as classes aninhadas estáticas 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, você não pode criar uma Inner2instância sem um Exterior, onde você pode criar um Inner1objeto independentemente.

Quando você usaria a classe Inner?

Pense em uma situação em que Class Ae Class Brelacionados, Class Bprecise acessar os Class Amembros e Class Bsó esteja relacionado a Class A. Classes internas entram em cena.

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

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

ou

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

Quando você usaria a classe interna estática?

Você definiria uma classe interna estática quando souber que ela não tem nenhum relacionamento com a instância da classe / classe superior envolvente. Se a sua classe interna não usa métodos ou campos da classe externa, é apenas um desperdício de espaço; portanto, torne-o estático.

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 de um objeto da classe / classe superior para funcionar. Isso pode ajudar a reduzir o número de objetos que seu aplicativo cria em tempo de execução.

Thalaivar
fonte
3
você quis dizer OuterClass.Inner2 inner = outer.new Inner2();?
Erik Kaplun
4
static inneré uma contradição em termos.
Marquês de Lorne
E classes internas também não são conhecidas como 'classes sem pilha'. Não use formatação de código para texto que não seja código e use-o para texto que seja.
Marquês de Lorne
30

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 a classe externa, métodos e campos estáticos e estáticos
  • Associado à instância da classe envolvente , para instanciar primeiro, é necessária uma instância da classe externa (observe o novo local da palavra-chave):

    Outerclass.InnerClass innerObject = outerObject.new Innerclass();
  • Não pode definir quaisquer membros estáticos em si

  • Não pode ter declaração de classe ou interface

Classe aninhada estática

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

  • Não está associado a nenhuma instância da classe envolvente. Portanto, para instanciar:

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

Semelhanças

  • Ambas as classes internas podem acessar até campos privados e métodos da classe externa
  • Além disso, a classe Outer tem acesso a campos privados e métodos 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 apenas em um local: se uma classe é útil para apenas uma outra classe, é lógico incorporá-la nessa classe e manter as duas juntas. Aninhar essas "classes auxiliares" torna seu pacote mais otimizado.

  • Aumenta o encapsulamento: considere duas classes de nível superior, A e B, em que B precisa acessar membros de A que, de outra forma, seriam declarados privados. Ao ocultar a classe B na classe A, os membros de A podem ser declarados privados e B pode acessá-los. Além disso, o próprio B pode ser oculto do mundo exterior.

  • Isso pode levar a um código mais legível e de manutenção: o aninhamento de pequenas classes nas classes de nível superior coloca o código mais perto de onde é usado.

Behzad Bahmanyar
fonte
26

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

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

No entanto, alguns outros pontos a serem lembrados são:

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

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

  • A classe anônima, por padrão, estende a classe pai ou implementa a interface pai e não há 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 questão maior que permanece em aberto é qual e quando usar? Bem, isso depende principalmente do cenário em que você está lidando, mas a leitura da resposta dada por @jrudolph pode ajudá-lo a tomar alguma decisão.

sactiw
fonte
15

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]

Na classe aninhada não estática, o objeto da classe interna existe dentro do objeto da classe externa. Portanto, esse membro de dados da classe externa é acessível à classe interna. Portanto, para criar um objeto da classe interna, primeiro devemos criar um objeto da classe externa.

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

Classe aninhada estática

Na classe estática aninhada, o objeto da classe interna não precisa de um objeto da classe externa, porque a palavra "estática" indica que não há necessidade de criar um objeto.

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

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

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

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 possui uma instância concreta. É carregado apenas 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 levam memória de pilha / pilha, porque não é necessário criar uma instância dessa classe. Portanto, a regra geral é tentar definir a classe aninhada estática, com escopo tão limitado quanto possível (privado> = classe> = protegido> = público) e, em seguida, convertê-la em classe interna (removendo o identificador "estático") e soltar o escopo, se for realmente necessário.

rmaruszewski
fonte
2
A primeira frase está incorreta. Não há tal coisa como ' a instância da classe interna', e instâncias de ele pode ser criado em qualquer momento após a classe externa foi instanciado. A segunda frase não segue da primeira frase.
Marquês de Lorne
11

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

Enquanto os atributos estáticos são instanciados antes que a classe seja instanciada por meio de seu construtor, os atributos estáticos dentro das classes estáticas aninhadas não parecem instanciados até depois que o construtor da classe é chamado, ou pelo menos não depois que os atributos são referenciados pela primeira vez, mesmo se eles são 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 'estático final'. a configuração de nested.innerItem não ocorre até depois que a classe é instanciada (ou pelo menos não depois que o item estático aninhado é referenciado pela primeira vez), como você pode ver ao comentar e descomentar as linhas às quais me refiro, acima. O mesmo não vale para 'outerItem'.

Pelo menos é o que estou vendo no Java 6.0.

HippoMan
fonte
10

Os termos são usados ​​de forma intercambiável. Se você quiser ser realmente pedante sobre isso, poderá definir "classe aninhada" para se referir a uma classe interna estática, uma que não possui instância anexa. No código, você pode ter algo parecido com isto:

public class Outer {
    public class Inner {}

    public static class Nested {}
}

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

Daniel Spiewak
fonte
2
'interior estático' é uma contradição em termos.
Marquês de Lorne
5
Não é uma convenção que define a classe interna como uma classe aninhada não estática, mas a JLS. docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3
Lew Bloch
1
E os termos não são "usados ​​de forma intercambiável".
Marquês de Lorne
por que estático no exemplo acima, dando erro no ide
DeV 24/04
10

No caso de criação de instância, a instância de classe interna não estática é criada com a referência do objeto da classe externa na qual está definida. Isso significa que ele tem uma instância abrangente. Mas a instância da classe interna estática é criada com a referência da classe Externa, não com a referência do objeto da classe externa. Isso significa que não há instância detalhada.

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….
  }
}
Ankit Jain
fonte
1
'interior estático' é uma contradição em termos. Uma classe aninhada é estática ou interna.
Marquês de Lorne
9

Não acho que haja muito a acrescentar aqui, a maioria das respostas explica perfeitamente as diferenças entre a classe aninhada estática e as classes Inner. No entanto, considere o seguinte problema ao usar classes aninhadas x 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 eles mantêm um ponteiro para a instância de sua classe envolvente, o que pode levar ao estouro de memória ou à exceção de excesso de pilha devido ao fato de o GC não poderá coletar lixo as classes anexas, mesmo que elas não sejam mais usadas. Para deixar 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 em // inner = null;O programa exibirá " Estou destruído! ", Mas, mantendo esse comentário, não será.
O motivo é que a instância interna branca ainda é referenciada pelo GC não pode coletá-la e, por referenciar (tem um ponteiro para) a instância externa, ela também não é coletada. Ter o suficiente desses objetos em seu projeto e pode ficar sem memória.
Comparado às classes internas estáticas, que não mantêm um ponto para a instância da classe interna porque ela não é relacionada à instância, mas relacionada à classe. O programa acima pode imprimir " Estou destruído! " Se você tornar a classe Inner estática e instanciada comOuter.Inner i = new Outer.Inner();

Adelin
fonte
8

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 agradável sobre as classes Nested, Inner, Member e de nível superior .

Wouter Coekaerts
fonte
8

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

Edit: Se você realmente quis dizer inner vs anonymous ... uma classe interna é apenas uma classe definida dentro de uma classe como:

public class A {
    public class B {
    }
}

Enquanto uma classe anônima é uma extensão de uma classe definida anonimamente, portanto, nenhuma classe "real é definida, como em:

public class A {
}

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

Edição adicional:

A Wikipedia afirma que há uma diferença em Java, mas eu trabalho com Java há 8 anos, e é a primeira vez que ouvi essa distinção ... sem mencionar que não há referências para fazer backup da declaração ... bottom linha, uma classe interna é uma classe definida dentro de uma classe (estática ou não) e aninhado é apenas outro termo para significar a mesma coisa.

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

Mike Stone
fonte
3
De acordo com a documentação do Java, há uma diferença entre uma classe interna e uma classe aninhada estática - as classes aninhadas estáticas não têm referências à sua classe anexa e são usadas principalmente para fins de organização. Você deve ver a resposta de Jegschemesch para obter uma descrição mais detalhada.
Mipadi
1
Eu acho que a diferença semântica é principalmente histórica. Quando escrevi um compilador C # -> Java 1.1, a referência da linguagem Java era muito explícita: a classe aninhada é estática, a classe interna não (e, portanto, possui esse $ 0). De qualquer forma, é confuso e fico feliz por não ser mais um problema.
Tomer Gabel
2
O JLS define "classe interna" em docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.1.3 e é por isso que é impossível ter um "interno" não estático classe "em Java. "Aninhado" NÃO é "apenas outro termo para significar a mesma coisa" e NÃO É VERDADE que "uma classe interna é uma classe definida dentro de uma classe (estática ou não)". Essa é uma informação incorreta.
18716 Lew Lew Bloch1
6

Alvo de aluno que é iniciante em Java e / ou classes aninhadas

As classes aninhadas podem ser:
1. Classes aninhadas estáticas.
2. Classes aninhadas não estáticas. (também conhecidas como classes internas ) => Lembre-se disso


1. Classes 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 NÃO pode dizer que uma classe aninhada também é uma classe interna .

Especialidade da classe interna:

  • A instância de uma classe interna tem acesso a todos os membros da classe externa, mesmo aqueles marcados como "particulares"


2. Classes aninhadas estáticas:
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 envolvente

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 envolvente

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 das classes estáticas:

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

Conclusão:
Pergunta: Qual é a principal diferença entre uma classe interna e uma classe aninhada estática em Java?
Resposta: basta passar por detalhes de cada classe mencionada acima.

VdeX
fonte
6

Classe interna e classe estática aninhada em Java 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 chamará classe estática aninhada em Java, enquanto a classe aninhada não estática é simplesmente chamada 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, a classe declarada não estática é conhecida como classe Inner em Java. existem três tipos de classe interna em Java:

1) Classe interna local - é declarada dentro de um bloco ou método de código.
2) Classe interna anônima - é uma classe que não tem nome para referência e inicializada no mesmo local em que é 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 é classe estática aninhada em Java?

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 ser tornada 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 está anexada a nenhuma instância anexa da classe Exterior. 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 o membro ou método não estático (instância) de dados .

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

roottraveller
fonte
2
"A classe aninhada estática não pode acessar o membro ou método não estático (instância) de dados." está incorreto e está causando confusão . Eles absolutamente têm acesso às informações da instância privada - desde que criem uma instância para acessar as informações da instância. Eles não têm uma instância de fechamento como as classes internas, mas têm acesso aos membros privados da instância de sua classe de fechamento.
TJ Crowder
5

Eu acho que as pessoas aqui devem notar para o Poster que: Static Nest Class é 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 classe normal. (porque a classe normal precisa de uma instância).

hqt
fonte
2
Isso tudo não faz sentido. Tudo isso mostra que uma classe interna não pode conter uma classe estática. A parte sobre 'não depende de qual classe ela contém' não tem sentido, assim como a frase a seguir.
Marquês de Lorne
5

Quando declaramos uma classe de membro estático dentro de uma classe, ela é conhecida como classe aninhada de nível superior ou 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 uma 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);
        }
    }
}
Pankti
fonte
"Quando declaramos uma classe de membro estática dentro de uma classe, ela é conhecida como classe aninhada de nível superior" Isso não faz sentido. "Uma classe de nível superior é uma classe que não é uma classe aninhada." Não existe uma "classe aninhada de nível superior".
Radiodef 8/08
3

A seguir, é apresentado um exemplo de static nested classe 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()); 

    }

}
Pritam Banerjee
fonte
3

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

Vamos dar uma olhada nos dois exemplos a seguir.

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

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

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

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

  3. BankAccount.Builder está associado apenas ao BankAccount. Nenhuma outra classe está relacionada ao BankAccount.Builder. portanto, é 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. Classe interna MyAdapter precisa acessar o membro da classe externa.

  2. No exemplo, o MyAdapter está associado apenas ao MyClass. Nenhuma outra classe está relacionada ao MyAdapter. portanto, é 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
        }
    }
}
Leogao
fonte
2

Um diagrama

insira a descrição da imagem aqui

A principal diferença entre static nestede non-static nestedclasses é que static nested não tem acesso a membros de classe externa não estáticos

yoAlex5
fonte
0

Antes de tudo, não existe uma classe chamada classe estática. O uso do modificador estático com a classe interna (chamada de classe aninhada) diz que ele é um membro estático da classe externa, o que significa que podemos acessá-lo como com outros membros estáticos e sem ter nenhum instância da classe externa. (Qual é o benefício da estática originalmente.)

A diferença entre o uso da classe Nested e da classe Inner regular é:

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

Primeiro, podemos instanciar Outerclass e depois podemos acessar Inner.

Mas se a classe é aninhada, a sintaxe é:

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

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

Então Oi
fonte
1
"... diz que é um membro estático da Classe Externa, o que significa ...": Não é incorreto pensar em uma classe aninhada estática como uma "classe membro" da Classe Externa, mas nas semelhanças com campos estáticos e métodos terminam aí. Uma classe aninhada estática não "pertence" à classe externa. Em quase todos os aspectos importantes, uma classe aninhada estática é uma classe de nível superior autônoma cuja definição de classe foi aninhada dentro da Classe Externa por conveniência de empacotamento (e, esperançosamente, porque existe uma associação lógica entre a classe aninhada e a Classe Externa ... embora não seja necessário).
scottb
1
'interior estático' é uma contradição em termos. As classes estáticas existem, no primeiro nível de aninhamento, e não são classes internas, por definição. Muito confuso.
Marquês de Lorne
0

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

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

Classes aninhadas são divididas em duas categorias: estática e não estática. Classes aninhadas 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 as 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 envolvente se essas forem estáticas. Ele não pode acessar membros não estáticos da classe externa. Assim como os 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 local.
  2. Aumenta o encapsulamento.
  3. Isso pode levar a um código mais legível e de manutenção.

Fonte: Os tutoriais Java ™ - Classes aninhadas

Mithun Debnath
fonte
-1

A diferença é que uma declaração de classe aninhada que também é estática pode ser instanciada fora da classe envolvente.

Quando você tem uma declaração de classe aninhada que não é estática, também conhecida como classe interna , o Java não permite instancia-la, exceto por meio da classe envolvente. O objeto criado a partir da classe interna é vinculado ao objeto criado a partir da classe externa, para que a classe interna possa fazer referência aos campos da externa.

Mas se for estático, o link não existe, os campos externos não podem ser acessados ​​(exceto por uma referência comum como qualquer outro objeto) e, portanto, você pode instanciar a classe aninhada sozinha.

DigitalRoss
fonte
1
Isso é falso. Há uma sintaxe especial para criar uma classe interna fora do escopo da classe envolvente.
Marquês de Lorne
-1

É bem simples, comparando classes locais estáticas e classes internas não estáticas
Diferenças:
Classe local estática:
pode acessar apenas membros estáticos da classe externa.
Não pode ter inicializadores estáticos
Não pode ser acessado diretamente de fora da função onde está declarado

Lau C
fonte
-2

Eu ilustrei vários possíveis cenários corretos e de erros que podem ocorrer no código java.

    class Outter1 {

        String OutStr;

        Outter1(String str) {
            OutStr = str;
        }

        public void NonStaticMethod(String st)  {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            //  below static attribute not permitted
            // static String tempStatic1 = "static";    

            //  below static with final attribute not permitted         
            // static final String  tempStatic1 = "ashish";  

            // synchronized keyword is not permitted below          
            class localInnerNonStatic1 {            

                synchronized    public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /* 
        //  static method with final not permitted
          public static void innerStaticMethod(String str11) { 

                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }                            

        }

        public static  void StaticMethod(String st)     {

            String temp1 = "ashish";
            final String  tempFinal1 = "ashish"; 

            // static attribute not permitted below
            //static String tempStatic1 = "static";     

            //  static with final attribute not permitted below
            // static final String  tempStatic1 = "ashish";                         

            class localInnerNonStatic1 {
                public void innerMethod(String str11) {
                    str11 = temp1 +" sharma";
                    System.out.println("innerMethod ===> "+str11);
                }

                /*
    // static method with final not permitted
    public static void innerStaticMethod(String str11) {  
                    str11 = temp1 +" india";
                    System.out.println("innerMethod ===> "+str11);
                }*/
            }

            // static class not permitted below
            //  static class localInnerStatic1 {   }    

        }

        // synchronized keyword is not permitted
        static  class inner1 {          

            static String  temp1 = "ashish";
            String  tempNonStatic = "ashish";
            // class localInner1 {

            public void innerMethod(String str11) {
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            public static void innerStaticMethod(String str11) {
                //  error in below step
                str11 = temp1 +" india";    
                //str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }
            //}
        }

        //synchronized keyword is not permitted below
        class innerNonStatic1 {             

//This is important we have to keep final with static modifier in non
// static innerclass below
            static final String  temp1 = "ashish";  
            String  tempNonStatic = "ashish";
            // class localInner1 {

            synchronized    public void innerMethod(String str11) {
                tempNonStatic = tempNonStatic +" ...";
                str11 = temp1 +" sharma";
                str11 = str11+ tempNonStatic +" sharma";
                System.out.println("innerMethod ===> "+str11);
            }

            /*
            //  error in below step
            public static void innerStaticMethod(String str11) {   
                            //  error in below step
                            // str11 = tempNonStatic +" india";                     
                            str11 = temp1 +" india";
                            System.out.println("innerMethod ===> "+str11);
                        }*/
                    //}
                }
    }
Ashish Sharma
fonte
1
Obviamente, a parte do código. E caso você não tenha notado: seu exemplo de código é super difícil de ler. Mesmo no meu enorme monitor de mesa, tenho uma barra de rolagem horizontal. Considere colocar seus comentários acima ou abaixo do que eles estão comentando - em vez de ficar para trás .
GhostCat