Il y a une violation de sonar:
Sonar Violation: Security - Le tableau est stocké directement
public void setMyArray(String[] myArray) {
this.myArray = myArray;
}
Solution:
public void setMyArray(String[] newMyArray) {
if(newMyArray == null) {
this.myArray = new String[0];
} else {
this.myArray = Arrays.copyOf(newMyArray, newMyArray.length);
}
}
Mais je me demande pourquoi?
Il se plaint que la matrice que vous stockez est la même que celle que détient l'appelant. Autrement dit, si l'appelant modifie ultérieurement ce tableau, le tableau stocké dans l'objet (et donc l'objet lui-même) changera.
La solution consiste à créer une copie dans l'objet lorsqu'il est transmis. Ceci s'appelle copie défensive . Une modification ultérieure de la collection n'affectera pas le tableau stocké dans l'objet.
C'est également une bonne pratique de le faire normalement lors du retour d'une collection (par exemple, lors d'un appel getMyArray()
correspondant). Sinon, le récepteur pourrait effectuer une modification et affecter l'instance stockée.
Notez que cela s'applique évidemment à toutes les collections mutables (et en fait à tous les objets mutables) - pas uniquement aux tableaux. Notez également que cela a un impact sur les performances qui doit être évalué avec d'autres préoccupations.
C'est ce qu'on appelle la copie défensive. Un article de Nice sur le sujet est "De qui s'agit-il, de toute façon?" de Brian Goetz, qui traite de la différence entre la sémantique de valeur et de référence pour les accesseurs et les setters.
Fondamentalement, le risque lié à la sémantique de référence (sans copie) est que vous pensiez à tort que vous êtes le propriétaire du tableau et que, lorsque vous le modifiez, vous modifiez également d'autres structures associées à des alias. Vous pouvez trouver de nombreuses informations sur la copie défensive et les problèmes liés à la création d'alias d'objet en ligne.
J'ai eu le même problème:
Sécurité - Le tableau est stocké directement Le tableau fourni par l'utilisateur 'palomitas' est stocké directement.
ma méthode originale:
public void setCheck(boolean[] palomitas) {
this.check=palomitas;
}
fixe tourné à:
public void setCheck(boolean[] palomitas) {
if(palomitas == null) {
this.check = new boolean[0];
} else {
this.check = Arrays.copyOf(palomitas, palomitas.length);
}
}
Autre exemple:
Sécurité - Le tableau est stocké directement Le tableau fourni par l'utilisateur
private String[] arrString;
public ListaJorgeAdapter(String[] stringArg) {
arrString = stringArg;
}
Fixé:
public ListaJorgeAdapter(String[] stringArg) {
if(stringArg == null) {
this.arrString = new String[0];
} else {
this.arrString = Arrays.copyOf(stringArg, stringArg.length);
}
}
Pour les éliminer, vous devez cloner le tableau avant de le stocker/le retourner, comme indiqué dans l'implémentation de classe suivante, afin que personne ne puisse modifier ou obtenir les données d'origine de votre classe, mais seulement une copie de celles-ci.
public byte[] getarrString() {
return arrString.clone();
}
/**
* @param arrStringthe arrString to set
*/
public void arrString(byte[] arrString) {
this.arrString= arrString.clone();
}
Je l'ai utilisé comme ça et maintenant je n'ai aucune violation de SONAR ...
C'est plus facile que tout cela. Pour éviter les violations de Sonar, il vous suffit de renommer le paramètre de méthode par quoi que ce soit d'autre.
http://osdir.com/ml/Java-sonar-general/2012-01/msg00223.html
public void setInventoryClassId(String[] newInventoryClassId)
{
if(newInventoryClassId == null)
{
this.inventoryClassId = new String[0];
}
else
{
this.inventoryClassId = Arrays.copyOf(newInventoryClassId, newInventoryClassId.length);
}
}
Dans certains cas, il s’agit d’une décision de conception qui n’est pas oubliée. Dans ces cas, vous devez modifier les règles de sonar pour les exclure afin que de tels problèmes ne s'affichent pas dans le rapport.
Aller dans la voie de la mise en œuvre défensive peut vous faire économiser beaucoup de temps… __.
http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained