不应在数组实例(SonarLint)上调用“ hashCode”和“ toString”

时间:2018-10-23 13:18:04

标签: java arrays 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 个答案:

答案 0 :(得分:3)

实际答案

SonarLint建议您,与其在数组实例上调用toString(),不如使用Arrays实用程序的方法。

建议您将代码更改为以下内容:

byte[] lblobPic;
lblobPic = r.get(ALUNO.PFOTO);
if (lblobPic != null) {
    String argStr = Arrays.toString(lblobPic);
    peopleDto.setUrlPic(argStr);
}

答案背后的原因

a)对人类的可读性

请考虑以下代码段:

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]

Linter规则假设开发人员实际上想要一个可读的数组输出(考虑其元素),并建议您使用Arrays.toString()方法执行此操作(如the documentation中所述)。 / p>

类似地,Arrays.hashCode()在哈希处理中考虑给定数组的元素(如the docoumentation所述)。

b)确定性
(根据@ andi-turner的建议)

Arrays实用程序的方法在构造字符串/计算哈希时仅考虑元素。当使用由相同序列(或其他类型的值)组成的输入数组时,您将总是以相同的字符串/哈希结束。 yourArray.toHashcode()yourArray.toString()并没有给您带来好处。

答案 1 :(得分:2)

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

最好还是在DTO中提供一个byte[]字段。


是否应该进一步处理?有图像嵌入。

如何(正常)将Base64用于带有嵌入式图像的HTML:

    String argStr = Base64.getEncoder().encode(lblobPic);
    String html = "<img src="data:image/jpeg;base64," + argStr + "\" alt=\"\">";

(此处假定为JPEG。)