"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 предполагается здесь.)

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