Sonar Violation: Security - Массив хранится напрямую

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

Sonar Violation: Security - Массив хранится напрямую

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

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

7 ответов

Решение

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

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

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

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

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

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

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

Безопасность - Массив хранится напрямую. Предоставленный пользователем массив '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;
    }

Исправлена:

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

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

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

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

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

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

    } 

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

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

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

Другие вопросы по тегам