Нарушение сонара: безопасность - массив хранится непосредственно

Нарушение сонара:

Нарушение сонара: безопасность - массив хранится непосредственно

public void setMyArray(String[] myArray) { 
  this.myArray = myArray; 
} 

Решение:

public void setMyArray(String[] newMyArray) { 
  if(newMyArray == null) { 
    this.myArray = new String[0]; 
  } else { 
   this.myArray = Arrays.copyOf(newMyArray, newMyArray.length); 
  } 
}

Но мне интересно, почему?

Ответ 1

Он жалуется, что массив, который вы храните, представляет собой тот же массив, который хранится вызывающим. То есть, если впоследствии вызывающий изменяет этот массив, массив, хранящийся в объекте (и, следовательно, сам объект), изменится.

Решение состоит в том, чтобы сделать копию внутри объекта при его передаче. Это называется защитным копированием. Последующая модификация коллекции не повлияет на массив, хранящийся внутри объекта.

Это также хорошая практика, как правило, делать это при возврате коллекции (например, в соответствующем вызове getMyArray()). В противном случае получатель может выполнить модификацию и повлиять на сохраненный экземпляр.

Обратите внимание, что это, очевидно, относится ко всем изменяемым коллекциям (и фактически ко всем изменяемым объектам), а не к массивам. Отметим также, что это влияет на производительность, которое необходимо оценивать наряду с другими проблемами.

Ответ 2

Это называется оборонительным копированием. Хорошая статья по теме "Чей это объект, в любом случае?" от Brian Goetz, в котором обсуждается разница между значениями и ссылочной семантикой для геттеров и сеттера.

В принципе, риск с ссылочной семантикой (без копии) заключается в том, что вы считаете себя владельцем массива, и когда вы его изменяете, вы также изменяете другие структуры, которые имеют псевдонимы в массиве. Вы можете найти много информации об защитном копировании и проблемах, связанных с алиасированием объектов в Интернете.

Ответ 3

У меня была такая же проблема:

Безопасность - массив хранится напрямую. Пользовательский массив "palomitas" хранится непосредственно.

мой оригинальный метод:

public void setCheck(boolean[] palomitas) {
        this.check=palomitas;
    }

исправлено:

public void setCheck(boolean[] palomitas) { 
      if(palomitas == null) { 
        this.check = new boolean[0]; 
      } else { 
       this.check = Arrays.copyOf(palomitas, palomitas.length); 
      } 
}

Другой пример:

Безопасность - массив хранится напрямую. Пользовательский массив

private String[] arrString;

    public ListaJorgeAdapter(String[] stringArg) {      
        arrString = stringArg;
    }

Fixed

public ListaJorgeAdapter(String[] stringArg) {  
    if(stringArg == null) { 
      this.arrString = new String[0]; 
    } else { 
      this.arrString = Arrays.copyOf(stringArg, stringArg.length); 
    } 
}

Ответ 4

Чтобы устранить их, вы должны клонировать массив перед его сохранением/возвратом, как показано в следующей реализации класса, поэтому никто не может изменять или получать исходные данные вашего класса, а только их копию.

public byte[] getarrString() {
    return arrString.clone();
}
/**
 * @param arrStringthe arrString to set
 */
public void arrString(byte[] arrString) {
    this.arrString= arrString.clone();
}

Я использовал его вот так, и теперь у меня нет никакого нарушения SONAR...

Ответ 5

Это более легко, чем все это. Вам нужно только переименовать параметр метода во все остальное, чтобы избежать нарушений сонара.

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);
            }

    } 

Ответ 6

Чтобы пройти оборонительный путь реализации, вы можете сэкономить много времени. В Guava вы получите еще одно приятное решение для достижения цели: ImmutableCollections

http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained

Ответ 7

Есть определенные случаи, когда это дизайнерское решение и не пропущено. В этих случаях вам нужно изменить правила сонара, чтобы исключить его, чтобы он не отображал такие проблемы в отчете.