为什么在打印到控制台时打印相同的字节数组导致两个不同的字符串?

时间:2018-03-27 03:33:36

标签: java arrays

我一直在实施一个与Java服务器通信的Android应用程序,他们发回字节数组和第四个字节数组。当我使用Arrays.toString(byte[])时,一切都按预期工作,但是打印到控制台不是这种情况。在这里,我将一个字节数组打印到Android中的控制台:

Log.d("byte array test"" + new byte[]{109, 89, -47, 12, 80, -13, 27, -9, 1, 117, -128, -98, 31, 2, -79, -36, -38, 78, -88, 74, 78, 105, 8, -53, 63, -96, -126, 85, -63, -105, 96, 124});

产生以下输出:

D/byte array test: [B@b4938b

关于Java:

System.out.println( new byte[]{109, 89, -47, 12, 80, -13, 27, -9, 1, 117, -128, -98, 31, 2, -79, -36, -38, 78, -88, 74, 78, 105, 8, -53, 63, -96, -126, 85, -63, -105, 96, 124}  "");

产生以下输出:

[B@43556938

任何人都可以解释原因吗?据我所知,他们都是两个字符串,所以他们都应该产生相同的输出。编码是我能想到差异的唯一原因,但我对此没有多少经验,所以我不确定。

2 个答案:

答案 0 :(得分:1)

这只是打印数组引用而不是其中的值。要获得可以使用的确切值,Arrays.toString

它肯定会调用to string方法,但是在Object类中实现toString的方式是打印类的名称,后跟hashcode:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

现在,对象哈希码是一个本机实现,它提供了对象引用的整数格式,因此对于上面检查的两种情况它们会有所不同。

答案 1 :(得分:1)

数组使用默认的Object.toString()方法进行打印,此方法使用Object.hashcode()方法。

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

docs中你可以看到hashcode的默认实现使用了对象的内部地址,因此它们不匹配是正常的,因为它们不是同一个对象(或者不在相同的地址)。

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要此实现技术。)

所以当数组是不同的对象时,如:

byte[] bytes1 = new String("HelloWorld").getBytes();
byte[] bytes2 = new String("HelloWorld").getBytes();

两个数组都包含完全相同的元素,但它们是不同的对象(并存储在不同的地址中),因此如果您打印,则会看到不同的值。

System.out.println(bytes1); // [B@7cc355be in my case
System.out.println(bytes2); // [B@6e8cf4c6 in my case