我正在通过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);
}
我应该如何更改代码以满足要求,为什么?
答案 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。)