"hashCode" и "toString" не должны вызываться для экземпляров массива (SonarLint)
Я передаю свой код через SonarLint, и я столкнулся с этим нарушением линтера:"hashCode" and "toString" should not be called on array instances
,
Это мой код:
byte[] lblobPic;
lblobPic = r.get(PEOPLE.PPIC);
if (lblobPic != null) {
String argStr = lblobPic.toString();
peopleDto.setUrlPic(argStr);
}
SonarLint дает следующий фрагмент кода в качестве подсказки для улучшения моего кода:
public static void main( String[] args ) {
String argStr = Arrays.toString(args);
int argHash = Arrays.hashCode(args);
}
Как мне изменить свой код, чтобы он соответствовал линтеру и почему?
2 ответа
Актуальный ответ
SonarLint предлагает вам вместо звонка toString()
на экземпляре массива лучше использовать Arrays
метод утилиты.
Он предлагает вам изменить свой код на что-то вроде строки:
byte[] lblobPic;
lblobPic = r.get(ALUNO.PFOTO);
if (lblobPic != null) {
String argStr = Arrays.toString(lblobPic);
peopleDto.setUrlPic(argStr);
}
Причина ответа
а) удобочитаемость для людей
Рассмотрим следующий фрагмент кода:
String[] strings = { "foo", "bar", "bla", "boo" };
System.out.println(strings.toString());
// prints: [Ljava.lang.String;@7852e922
System.out.println(Arrays.toString(strings));
// prints: [foo, bar, bla, boo]
Правило Линтера предполагает, что разработчик действительно хочет читаемый вывод массива (с учетом его элементов) и предлагает вам использовать Arrays.toString()
метод, который делает это (как указано в документации).
Так же, Arrays.hashCode()
рассматривает элементы данного массива в хешировании (как указано в документации).
б) детерминизм
(согласно предложению Энди Тернера)
Arrays
методы утилиты, учитывают только элементы при построении строки / вычислении хеша. Вы всегда будете получать одну и ту же строку / хеш при использовании входного массива, состоящего из одинаковых строк (или значений другого типа) в той же последовательности. yourArray.toHashcode()
или же yourArray.toString()
не дает вам этого.
String argStr = lblobPic.toString();
должно быть лучше
String argStr = Arrays.toString(lblobPic);
так как оригинальный Object.toString даст загадочный шестнадцатеричный адрес.
Однако, чего вы хотите достичь, хранить байты как String в java запрещено, так как java использует Unicode для String и char (два байта, UTF-16), всегда с преобразованием (предполагаемой кодировки текста этих байтов),
Иногда такие байты кодируются Base64:
byte[] lblobPic = r.get(ALUNO.PFOTO);
if (lblobPic != null) {
String argStr = Base64.getUrlEncoder().encode(lblobPic);
peopleDto.setUrlPic(argStr);
}
Лучше еще обеспечить byte[]
поле в DTO.
Если дальнейшая обработка будет проблемой; существует вложение изображений.
Как (обычный) Base64 можно использовать для HTML со встроенным изображением:
String argStr = Base64.getEncoder().encode(lblobPic);
String html = "<img src="data:image/jpeg;base64," + argStr + "\" alt=\"\">";
(JPEG предполагается здесь.)