12
votes

Y a-t-il une performance sur le dessus d'une classe intérieure privée en Java?

Lorsque j'ai des classes intérieures avec des méthodes privées ou des champs, le compilateur doit créer des méthodes d'accessor protégées par package synthétiques pour permettre à la classe externe d'accéder à ces éléments privés (et inversement).

Pour éviter cela, je suis habituellement Faites de tous les champs et méthodes et constructeurs-protecteurs au lieu de privé.

Mais que diriez-vous de la visibilité de la classe elle-même? Y a-t-il une surcharge sur xxx

contre xxx

Notez que le constructeur est protégé par un paquet dans les deux cas ou Faire le changement privé de classe qui?


4 commentaires

Dupliqué possible de Les classes intérieures sont-elles légères?


Je me demande si la visibilité réduite est exploitée par Hotspot de quelque manière que ce soit. Je me demande également si les compilateurs Java peuvent utiliser ce fait pour exclure la classe de la considération en dehors de sa portée de la visibilité. Question intéressante, mais je ne pense pas qu'il y ait un avantage pratique.


@Ron: Le compilateur / IDE vérifiera certainement la visibilité et effectuera des erreurs de compilation ou de la retirer de l'autocomplete. Je me demandais simplement si quelque chose se passe à l'heure.


Ouais je voulais dire pour une génération plus rapide de la compilation et de l'autocomplete


3 Réponses :


18
votes

Avez-vous essayé de la compiler et de comparer le code d'octets? Voici mes résultats. Pour: xxx

ce qui précède les rendements ci-dessus Les fichiers * .class suivants: xxx

maintenant, si je déplace les fichiers de classe, supprimez le < Code> privé modificateur et recompilez, je reçois: xxx

si vous regardez le VM Spec sur les fichiers de classe , vous verrez qu'il existe un champ de bits de taille constante pour spécifier les modificateurs d'accès , donc il ne devrait pas être surprenant que les fichiers générés soient de la même taille.

En bref, vos modificateurs d'accès n'affectent pas la taille du code d'octet généré (il ne doit pas non plus avoir d'impact sur la performance. , Soit). Vous devez utiliser le modificateur d'accès qui a le plus de sens.

Je devrais également ajouter qu'il existe une légère différence si vous modifiez la classe interne d'être déclarée statique à ne pas être déclarée statique , car il implique un champ supplémentaire référençant la classe extérieure. Cela prendra légèrement plus de mémoire que si vous avez déclaré la classe interne statique , mais vous seriez fou d'optimiser pour cela (utilisez statique où il est logique, et où Vous en avez besoin pour être non statique, le rendre non statique, mais ne convolitez pas votre conception uniquement pour enregistrer un pointeur de mémoire ici ou là).


1 commentaires

@Thilo, c'est parce que vous ne référez rien dans la classe extérieure; Si vous aviez besoin d'accéder aux membres ou aux fonctions de la classe extérieure, il y aurait une raison légitime de le rendre non statique.



9
votes

Il ne devrait y avoir aucune différence de performance entre une classe intérieure privée et une classe intérieure non privée.

Il ne devrait y avoir aucune différence de performance entre une classe intérieure statique (privée ou non) et une classe extérieure.

Il existe une petite différence de performance entre une classe interne statique et une classe intérieure non statique. Cette différence est due au fait que l'étui non statique a une référence cachée à l'instance de sa classe jointe. Ceci est transmis comme paramètre supplémentaire sur le constructeur de classes internes et stocké dans une variable cachée.


4 commentaires

Et (pour couvrir tous les cas) Il existe également une faible différence de performance lorsqu'il passe en passant une visibilité privée (de champs, de méthodes et de constructeurs) avec des classes intérieures.


@Thilo - y a-t-il? Pourquoi? AFAIK, les règles de visibilité sont appliquées par le compilateur et par le vérificateur. Au moment où vous arrivez à exécuter (ou à compiler), les byTecodes, les contrôles de visibilité ont toutes été effectués et il n'y a pas d'impact sur la performance.


La différence de performance provient de l'accès à une méthode privée via une méthode d'emballage synthétique générée par le compilateur par opposition à l'accès d'une méthode protégée par un paquet directement.


@Thilo - euh ... je vois. Bien que je m'attends à ce que le compilateur JIT signale l'appel.



4
votes

Il est très improbable que cela provoque jamais de ralentissement significatif.

Un problème à prendre connaissance avec des classes intérieures non statiques est qu'ils contiennent une référence à l'instance de la classe entourant.

En tant que tel, cela peut provoquer des «fuites de mémoire», car l'instance de la jointe ne peut pas être recueillie. Si vous passez des cas de classes intérieures aux appelants, vous passez également une instance de la classe enfermante.

Ce n'est pas le cas avec des classes intérieures statiques!

Rendre tous les champs de champs protégés pour empêcher les méthodes de synthèse n'est pas conseillé. Vous abandonnez l'encapsulation qui est une chose précieuse à avoir. Quelles sont vos préoccupations? Taille de vos fichiers de classe pour le code supplémentaire?


6 commentaires

L'encapsulation est la plus importante au niveau du package, alors je n'abandonne pas beaucoup ici. Des paquets extérieurs (c'est-à-dire le code des autres personnes) ne peuvent pas voir la classe de toute façon.


@Thilo Juste parce que cela est vrai maintenant, il ne signifie pas nécessairement que cela restera pour toujours de cette façon. L'encapsulation vous prépare plus pour les personnes non planifiées que pour les attentes.


@TheBlastone: Encore une fois, je ne brise pas l'encapsulation du tout ici. Tout est encore package-privé.


"L'encapsulation est la plus importante au niveau du package" Il n'y a pas d'encapsulation au niveau du package. Si vous faites vos champs non privés, votre classe perd tout contrôle de ce qui se trouve à l'intérieur. Vos objets peuvent alors entrer dans un état non valide à tout moment.


"Si la classe extérieure détient des données considérables, il peut réduire les performances de l'application." Stackoverflow.com/a/8257808/521754


Je ne vois aucune information pertinente pour soutenir cette déclaration. Je suppose que l'auteur signifiait que la future mémoire significative à travers des classes non statiques peut ralentir la collecte des ordures. Ouais. Pourrait être.