"hashCode" 和 "toString" 不应在数组实例上调用 (SonarLint)
"hashCode" and "toString" should not be called on array instances (SonarLint)
我正在通过 SonarLint 传递我的代码,我遇到了这个 linter 违规行为:
"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);
}
我应该如何更改我的代码以满足 linter,为什么?
实际答案
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 中所述) .
类似地,Arrays.hashCode()
在散列中考虑给定数组的元素(如 the docoumentation 中所述)。
b) 决定论
(根据@andi-turner 的建议)
Arrays
实用程序的方法,在构造字符串/计算哈希时仅考虑元素。当使用由相同序列中的相同字符串(或另一种类型的值)组成的输入数组时,您将始终得到相同的 string/hash。 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);
}
最好在 DTO 中提供一个 byte[]
字段。
应该是进一步处理有问题;存在图像嵌入。
如何(正常)Base64 用于 HTML 嵌入图像:
String argStr = Base64.getEncoder().encode(lblobPic);
String html = "<img src="data:image/jpeg;base64," + argStr + "\" alt=\"\">";
(此处假设为 JPEG。)
我正在通过 SonarLint 传递我的代码,我遇到了这个 linter 违规行为:
"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);
}
我应该如何更改我的代码以满足 linter,为什么?
实际答案
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 中所述) .
类似地,Arrays.hashCode()
在散列中考虑给定数组的元素(如 the docoumentation 中所述)。
b) 决定论
(根据@andi-turner 的建议)
Arrays
实用程序的方法,在构造字符串/计算哈希时仅考虑元素。当使用由相同序列中的相同字符串(或另一种类型的值)组成的输入数组时,您将始终得到相同的 string/hash。 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);
}
最好在 DTO 中提供一个 byte[]
字段。
应该是进一步处理有问题;存在图像嵌入。
如何(正常)Base64 用于 HTML 嵌入图像:
String argStr = Base64.getEncoder().encode(lblobPic);
String html = "<img src="data:image/jpeg;base64," + argStr + "\" alt=\"\">";
(此处假设为 JPEG。)