2008-12-17 26 views
8

Récemment, j'ai travaillé sur des avertissements FindBugs concernant l'exposition de l'état interne, c'est-à-dire quand une référence à un tableau a été renvoyée au lieu de renvoyer une copie du tableau. J'ai créé quelques modèles pour faciliter la conversion de ce code.Modèles d'éditeur pour la programmation défensive

Lequel avez-vous créé pour soutenir la programmation défensive et que vous voulez partager avec la foule SO?

Les modèles que j'ai créé jusqu'à présent (à titre d'exemple):

Pour créer une copie d'un tableau de revenir d'une méthode:

Pour cloner un objet:

(${o}!= null?(${type})${o}.clone():null) 

Répondre

3

J'aime avoir comme modèle un « plus sûr » est égal à() Définition:

/** 
* Implement equals based on ${cursor}. <br /> 
* See {@link #compareTo(Object) compareTo} 
* @see java.lang.Object#equals(java.lang.Object) 
*/ 
public boolean equals(final Object anObject) 
{ 
    boolean res = false; 
    if(anObject == null) { return false; } 
    if(anObject == this) { return true; } 
    if(anObject.getClass() == this.getClass()) 
    { 
     res = this.compareTo(anObject) == 0; 
    } 
    return res; 
} 

Pour être sûr d'éviter toujours l'équation: méthode equals overrides égaux dans superclasse et ne peut être symétrique (EQ_OVERRIDING_EQUALS_NOT_SYMMETRIC) , où:

Cette classe définit une méthode égale qui remplace une méthode égale dans une superclasse. Les deux méthodes méthodes equals utilisent instanceof pour déterminer si deux objets sont égaux.

Ceci est lourd de péril, car il est important que la méthode égale soit symétrique (en d'autres termes, a.equals(b) == b.equals(a)).
Si B est un sous-type de A et A est égal méthode vérifie que l'argument est un instanceof A et B méthode equals vérifie que l'argument est un instanceof B, il est fort probable que la relation d'équivalence définie par ces méthodes ne sont pas symétrique.


Ceci est seulement pour les classes de mise en œuvre Comparable et permet:

  • une mise en œuvre d'égal à égal qui est toujours le même;
  • toutes les logiques de comparaison à localiser en un seul endroit (la fonction compareTo());
  • la conformité avec le javadoc de Comparable#compareTo() demandant de s'assurer que (x.compareTo(y)==0) == (x.equals(y)) (fortement recommandé, mais pas strictement nécessaire cependant). Clone sur un tableau est bon.
+0

J'inverserais l'initialisation "boolean res" et le test d'égalité de classe. Ensuite, le code "else" peut être déplacé dans la clause "then". Je pense que cela rend la compréhension plus facile et moins sujette aux erreurs. –

+0

@Randy: modèle corrigé – VonC

+0

Mais ce modèle ne fonctionne que si la classe implémente Comparable, non? Est-ce que toutes vos classes implémentent des comparables? Si oui, quels sont les avantages et les frais généraux de codage en valent-ils la peine? – dhiller

2

Pas un modèle, mais j'utilise array.clone() au lieu de System.arraycopy(). Y-a-t-il un problème avec cela?

Edit: Un modèle que j'utilise la mise en œuvre d'un décorateur, en particulier pour une interface avec de nombreuses méthodes:

wrapped.${enclosing_method}(${enclosing_method_arguments}) 

Il génère une implémentation de la méthode actuelle en déléguant l'appel à une instance enveloppée, empêchant ainsi copier/coller des erreurs.

+0

cloner sur un objet non-final non fiable est un problème parce que le clonage pourrait être surchargé pour faire quelque chose de méchant/stupide. –

+0

Est-ce différent de Source/Generate Delegate Methods? –

+0

Donc une sous-classe codée malveillante de java.util.Date pourrait remplacer l'opération clone() pour faire des choses désagréables, non? Si oui, je devrais ajuster le modèle de clone en conséquence ... Des suggestions? – dhiller