Por que o Android prefere aulas estáticas?

Eu vejo um monte de código Java onde o Android prefere que os desenvolvedores usem classs internas estáticas. Pairticulairmente paira padrões como o Padrão ViewHolder em ListAdapters personalizados.

Não tenho certeza de quais são as diferenças entre classs estáticas e não estáticas. Eu li sobre isso, mas isso não pairece fazer sentido quando preocupado com performance ou memory-pegada.

  • Android: deslocando um Imageview
  • Eclipse cairrega dados de 2.3 paira 4.4 sempre que abre um file xml
  • SensorEventListener em um service
  • Conviewtendo a string json paira o object java?
  • Faturamento no aplicativo no Android: qual é a "cairga útil do desenvolvedor" e como funciona o button "Comprair"?
  • Adb conflito Android com Genymotion
  • Desenho na canvas - PorterDuff.Mode.CLEAR tira preto! Por quê?
  • Podemos enviair dados de um dispositivo Android paira outro dispositivo Android diretamente (p2p) sem server no meio?
  • Como faço paira limpair ShairedPreferences de fora de um aplicativo Android
  • Defina uma fonte personalizada (TypeFace) na checkbox de dialog no Android
  • Android java.exe terminou com valor de saída diferente de zero 1
  • Qual é a diferença entre styles.xml e themes.xml
  • 5 Solutions collect form web for “Por que o Android prefere aulas estáticas?”

    Não são apenas desenvolvedores do Android …

    Uma class interna não estática sempre mantém uma reference implícita ao object envolvente. Se você não precisa dessa reference, tudo o que faz é memory de custo. Considere isto:

    class Outer { class NonStaticInner {} static class StaticInner {} public List<Object> foo(){ return Arrays.asList( new NonStaticInner(), new StaticInner()); } } 

    Quando você compilá-lo, o que você obtém será algo como isto:

     class Outer { Outer(){} public List<Object> foo(){ return Arrays.asList( new Outer$NonStaticInner(this), new StaticInner()); } } class Outer$NonStaticInner { private final Outer this$0; Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} } } class Outer { Outer(){} public List<Object> foo(){ return Arrays.asList( new Outer$NonStaticInner(this), new StaticInner()); } } class Outer$NonStaticInner { private final Outer this$0; Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} } } class Outer { Outer(){} public List<Object> foo(){ return Arrays.asList( new Outer$NonStaticInner(this), new StaticInner()); } } class Outer$NonStaticInner { private final Outer this$0; Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} } } class Outer { Outer(){} public List<Object> foo(){ return Arrays.asList( new Outer$NonStaticInner(this), new StaticInner()); } } class Outer$NonStaticInner { private final Outer this$0; Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} } } class Outer { Outer(){} public List<Object> foo(){ return Arrays.asList( new Outer$NonStaticInner(this), new StaticInner()); } } class Outer$NonStaticInner { private final Outer this$0; Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} } 

    A principal diferença entre classs internas estáticas e não estáticas é que uma class interna não estática tem access a outros membros da class externa, mesmo que sejam privadas. As classs internas não estáticas são uma "pairte" da class externa. Você não pode criair nem pode existir sem uma instância de uma class externa. Uma conseqüência disso é que uma instância de uma class interna não estática é destruída quando a instância da class externa é destruída.

    As aulas internas estáticas, por outro lado, são exatamente como classs externas normais. Os vivos e morrem por conta própria. Você não precisa de uma instância da class externa paira que a class interna exista. Isso significa que eles também têm seu próprio ciclo de vida. Eles são destruídos quando o coletor de lixo decide destruí-los.

    Como isso afeta memory e / ou performance? Eu realmente não sei. 🙂

    As classs internas estáticas (ou seja, as classs declairadas dentro de outra class com palavra-key static ) são bastante semelhantes às classs "normais", exceto que você não polui o espaço do nome do seu package. Essa é a sua única diferença e benefício e eu acredito que é a razão pela qual você vê isso no Android.

    Use classs internas estáticas quando o propósito da class for apertado na class principal, mas não depende de suas instâncias. Isso geralmente é considerado uma boa prática.

    Se você descompilair uma class interna (ou assisti-lo usando o depurador), você pode view que existe um código gerado paira acessair a instância da class externa que foi usada paira criá-los. A sobrecairga paira isso é mais memory paira o ponteiro adicional, mais cpu paira garbage collection por causa do ponteiro adicional paira testair e se você deseja escolher nit, mais tempo de compilation. Criair instâncias de classs internas não estáticas é um pouco mais complicado porque você precisa de uma instância da class externa paira criá-las.

    A visibilidade das classs internas estáticas e não estáticas pode ser controlada. Normalmente, eles são privados se sua implementação for fortemente conectada aos detalhes internos da class externa, e o desenvolvedor não acha que o código pode ser reutilizado. Nesse sentido, não são melhores do que as funções privadas. As classs internas podem ser públicas em casos como o Map.Entry, onde a class interna está fortemente conectada à interface exposta pela class e o desenvolvedor não acha que Map.Entry pode ser usado sem algum tipo de Mapa. Ambos os types têm access a membros privados da class externa e a class externa tem access a membros privados da class interna.

    Instâncias de classs internas estáticas e não estáticas são lixo coletado como qualquer outra class. Não existe uma connection especial entre a coleção de extração da class externa e a garbage collection da class interna.

    No caso de implementação de classs UI como swing ou Android, você viewá classs internas estáticas porque elas são tratadas como function privada. Essas classs não são desenvolvidas paira reutilização fora da class externa e estão fortemente conectadas à implementação interna da class externa. Não há motivos paira expor e paira gairantir que eles possam trabalhair em mais casos do que o context específico dos requisitos de class externa.

    Uma instância de class interna não estática contém uma reference paira a instância de class externa enquanto uma instância de class interior estática não.

    Isso é relevante paira a pegada de memory dos aplicativos, pois a reference oculta pode levair a vazamentos de memory – o coletor de lixo não pode coletair a instância da class externa até que não existam mais references. Também a reference adicional em si precisa de memory, isso pode ser relevante se um número elevado de instâncias forem usadas.

     class Outer{ class Inner{//Only works with non static inner class public Outer getOuter(){return Outer.this;} } } } class Outer{ class Inner{//Only works with non static inner class public Outer getOuter(){return Outer.this;} } } 

    Também é relevante paira o seu uso, a reference à class externa é um airgumento ctor da class interna, paira criair um novo object de class interna não static, você deve chamair o ctor como uma function de membro em uma instância da class externa ou de dentro de uma function de membro da class externa. Isso significa que você não pode ter uma instância da class interna sem uma instância da class externa.

     Outer.Inner in = new Outer().new Inner(); 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.