【问题标题】:"hashCode" and "toString" should not be called on array instances (SonarLint)不应在数组实例上调用“hashCode”和“toString”(SonarLint)
【发布时间】:2019-03-27 18:07:25
【问题描述】:

我通过 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 给出以下代码 sn-p 作为改进我的代码的提示:

public static void main( String[] args )  {
    String argStr = Arrays.toString(args);
    int argHash = Arrays.hashCode(args);    
}

我应该如何更改我的代码以满足 linter 的要求,为什么?

【问题讨论】:

  • 你不能......你尝试了什么?这很简单
  • 为什么要将args String 数组传递给不带参数的方法?
  • 我认为这是一个不值得反对的好问题!总的来说:我认为这个问题与 jooq 无关。

标签: java arrays sonarlint


【解决方案1】:

实际答案

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

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

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

回答背后的原因

a) 人类可读性

考虑以下代码sn-p:

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 实用程序的方法在构造字符串/计算哈希时仅考虑元素。当使用由相同序列中的相同字符串(或另一种类型的值)组成的输入数组时,您将始终得到相同的字符串/哈希值。 yourArray.toHashcode()yourArray.toString() 不会给你。

【讨论】:

  • 看到它是一个byte 数组,他们实际上可能需要new String(lblobPic) 的变体。不过,不知道 OP 的确切用例。
  • 我认为值得明确指出的另一件事是String[] strings2 = { /* the same elements */ }; 将有不同的toString()hashCode()7852e922 不是从元素计算出来的。
【解决方案2】:
String argStr = lblobPic.toString();

最好是

String argStr = Arrays.toString(lblobPic);

因为原始 Object.toString 会给出一个神秘的十六进制地址。

但是,您想要实现的是,将字节存储为 String 在 java 中是不行的, 因为 java 对 String 和 char 使用 Unicode(两个字节,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。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 2011-02-26
    • 1970-01-01
    • 2021-11-27
    • 2020-06-19
    相关资源
    最近更新 更多