web-dev-qa-db-fra.com

PMD: Évitez d’instancier de nouveaux objets dans des boucles

J'ai un problème avec la règle PMD Avoid instantiating new objects inside loops. Voici un exemple de code:

import Java.awt.Dimension;

public class PMDDemo {
    public static void main(final String[] args) {
        final Dimension[] arr = new Dimension[10];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new Dimension(i, i); // rule violation here
        }
    }
}

PMD me donne la violation de règle mentionnée ci-dessus à l'endroit indiqué dans le code. Comment suis-je supposé créer n instances d'une classe sans les créer dans une boucle?

Je sais que certaines règles de PMD sont controversées (comme la règle onlyOneExit ). Mais jusqu'à présent, j'ai au moins compris l'idée qui les sous-tendait. Je ne comprends pas le raisonnement derrière cette règle. Est-ce que quelqu'un peut m'aider avec ça?

21
brimborium

Pour votre cas d'utilisation spécifique, cela n'a aucun sens puisque vous conservez la référence au nouvel objet after the loop. Il n'y a donc pas de réelle alternative à votre solution.

Plus généralement, créer des objets éphémères en Java est peu coûteux * (à part le coût caché que le GC exécutera plus souvent). En particulier, l'attribution est presque gratuite et le temps de GC dépend principalement de la quantité d'objets accessibles - les objets morts n'augmentent pas le temps de GC pour des algorithmes GC typiques.

Le JIT peut également effectuer diverses optimisations s’il détecte la création d’objets inutiles.

Évidemment, la création d'inutiles n'est pas une pratique recommandée, mais essayer de réutiliser des objets est souvent contre-productif.

Comme exemple pratique, vous pouvez regarder cet article qui montre que créer un nouvel ensemble dans une boucle revient moins cher que d'en créer un avant la boucle et de l'effacer à chaque itération.

* Merci @RichardTingle pour le lien

24
assylias
for (int i = 0; i < arr.length; i++) {
  arr[i] = new Dimension(i, i); // rule violation here
}

La résolution ci-dessus peut être résolue par 

 for (int i = 0; i < arr.length; i++) {
   arr[i] = createNewDimension(i,i); // rule violation here
 }

 private static Dimension createNewDimension(i,i) {
   return new Dimension(i, i);
 }

nous ne devrions pas utiliser directement nouvel opérateur dans une boucle mais simplement déplacer ceci dans une méthode privée. 

0
Vishnu Ranganathan