38 votes

Pourquoi Android préfère-t-il les classes statiques?

Je vois beaucoup de code Java dans lequel Android préfère que les développeurs utilisent des classes internes statiques. Particulièrement pour les modèles tels que le modèle ViewHolder dans les ListAdapters personnalisés.

Je ne suis pas sûr des différences entre les classes statiques et non statiques. J'ai lu des articles à ce sujet, mais cela ne semble pas avoir de sens lorsqu'il est question de performances ou d'empreinte mémoire.

69voto

gustafc Points 13552

Il n'y a pas que les développeurs Android ...

Une classe interne non statique conserve toujours une référence implicite à l'objet englobant. Si vous n'avez pas besoin de cette référence, cela ne vous coûtera que de la mémoire. Considère ceci:

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

Lorsque vous le compilerez, vous obtiendrez quelque chose comme ceci:

 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(){}
}
 

25voto

Jere.Jones Points 5394

La principale différence entre statiques et non statiques de classes internes est qu'un non-statique à l'intérieur de la classe a accès à d'autres membres de l'extérieur de la classe, même si ils sont privés. Non statique les classes internes sont une "partie" de l'extérieur de la classe. Vous ne pouvez pas créer ni ne peuvent exister sans une instance de l'extérieur de la classe. Une conséquence de ceci est qu'un exemple de non-statique les classes internes sont détruits lorsque l'extérieur de la classe de l'instance est détruite.

Statique à l'intérieur des classes, d'autre part, sont, tout comme normale extérieur des classes. Le vivre et de mourir sur leur propre. Vous n'avez pas besoin d'une instance de l'extérieur de la classe pour l'intérieur de la classe d'exister. Cela signifie qu'ils ont aussi leur propre cycle de vie. Ils sont détruits lorsque le garbage collector décide de les détruire.

Comment cela affecte la mémoire et/ou la performance? Je ne sais vraiment pas. :)

15voto

Viliam Points 2219

Les classes internes statiques (c'est-à-dire les classes déclarées dans une autre classe avec le mot-clé static ) sont assez similaires aux classes "normales" sauf que vous ne polluez pas l'espace de noms de votre paquet. C'est leur (unique) différence et avantage et je crois que c'est la raison pour laquelle vous le voyez dans Android.

Utilisez des classes internes statiques lorsque l'objectif de la classe est étroitement lié à la classe principale, mais ne dépend pas de ses instances. Ceci est généralement considéré comme une bonne pratique.

7voto

josefx Points 8417

Non statique intérieure instance de classe contient une référence à l'extérieur de la classe de l'instance tout en statique intérieure instance de la classe ne l'est pas.

Ce qui est pertinent pour les applications de la mémoire caché de référence peut conduire à des fuites de mémoire - le garbage collector ne peut percevoir de l'extérieur de la classe de l'instance jusqu'à ce que pas plus de références existent. Aussi la référence supplémentaire lui-même a besoin de la mémoire, ce qui peut être pertinente que si un nombre élevé de cas sont utilisés.

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

Il est également adapté pour son utilisation, la référence à l'extérieur de la classe est un ctor argument de l'intérieur de la classe, pour créer un nouveau non statique à l'intérieur de la classe de l'objet, vous devez appeler le ctor comme un memberfunction sur une instance de l'extérieur de la classe ou de l'intérieur d'une memberfunction de l'extérieur de la classe. Cela signifie que vous ne pouvez pas avoir une instance de l'intérieur de la classe sans une instance de l'extérieur de la classe.

Outer.Inner in = new Outer().new Inner();

5voto

shoren Points 513

Si vous décompiler un à l'intérieur de la classe (ou les visionner à l'aide du débogueur) vous pouvez voir qu'il y a le code généré pour l'accès à l'instance de l'extérieur de la classe qui a été utilisé pour les créer. Les frais généraux pour ce qui est de plus de mémoire pour le pointeur supplémentaires, plus de cpu pour la collecte des ordures à cause de pointeur supplémentaires pour tester, et si vous voulez la petite bête, plus le temps de compilation. La création des instances de non-statiques, les classes internes est un peu plus compliqué parce que vous avez besoin d'une instance de l'extérieur de la classe pour les créer.

La visibilité à la fois statiques et non statiques et les classes internes peuvent être contrôlés. Habituellement, ils sont privés si leur mise en œuvre est fortement connnected de détails internes de l'extérieur de la classe, et le développeur ne pense pas que le code peut être réutilisé. En ce sens, ils ne sont pas meilleurs que les fonctions privées. Les classes internes peuvent être publics dans des cas comme Carte.Entrée, où l'intérieur de la classe est fortement connecté à l'interface exposée par la classe, et le développeur ne pense pas que la Carte.L'entrée peut être utilisé sans une sorte de Carte. Les deux types ont accès aux membres privés de l'extérieur de la classe et à l'extérieur de la classe a accès aux membres privés de l'intérieur de la classe.

Les Instances statiques et non statiques et les classes internes sont des ordures collectées comme toutes les autres classes. Il n'y a pas de relation particulière entre le grabage collection de l'extérieur de la classe et de la collecte des déchets de l'intérieur de la classe.

Dans le cas de classes de l'INTERFACE utilisateur de mise en œuvre comme de la balançoire ou android, vous verrez statique à l'intérieur des classes, car ils sont traités comme fonction privée. Ces classes ne sont pas développés pour la réutilisation en dehors de l'extérieur de la classe et sont fortement liées à la mise en œuvre interne de l'extérieur de la classe. Il n'y a pas de raison de les exposer et de s'assurer qu'ils peuvent travailler dans les cas plus que le contexte spécifique de l'extérieur de la classe des exigences.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X