Java:“背后的语法和含义? 二进制/地址?

嘿, 我想弄清楚[B @前缀在java中意味着什么。 当我尝试打印字节数组时它们出来了。 但是,大小为32和大小为4的字节数组的长度相同。 始终“[@ B1234567”。

这是什么? 此外,它们具有仅打印hex值的属性。 我知道它不能只是二进制打印,因为会出现随机扩展的ascii字符。

下面是byte []到byte []哈希表映射打印的示例,其中映射由冒号分隔,这些是4字节键和32字节元素的字节数组。

[B@1ef9157:[B@1f82982 [B@181ed9e:[B@16d2633 [B@27e353:[B@e70e30 [B@cb6009:[B@154864a [B@18aaa1e:[B@3c9217 [B@20be79:[B@9b42e6 [B@16925b0:[B@14520eb [B@8ee016:[B@1742700 [B@1bfc93a:[B@acb158 [B@107ebe1:[B@1af33d6 [B@156b6b9:[B@17431b9 [B@139b78e:[B@16c79d7 [B@2e7820:[B@b33d0a [B@82701e:[B@16c9867 [B@1f14ceb:[B@89cc5e [B@da4b71:[B@c837cd [B@ab853b:[B@c79809 [B@765a16:[B@1ce784b [B@1319c:[B@3bc473 

您正在查看对象ID,而不是内容的转储。

  • [表示数组。
  • B表示字节。
  • @将类型与ID分开。
  • hex数字是对象ID或哈希码。

如果打算打印数组的内容,有很多方法。 例如:

 byte[] in = new byte[] { 1, 2, 3, -1, -2, -3 }; System.out.println(byteArrayToString(in)); String byteArrayToString(byte[] in) { char out[] = new char[in.length * 2]; for (int i = 0; i < in.length; i++) { out[i * 2] = "0123456789ABCDEF".charAt((in[i] >> 4) & 15); out[i * 2 + 1] = "0123456789ABCDEF".charAt(in[i] & 15); } return new String(out); } 

可以在JNI文档中找到类型命名的完整列表 。

这是整个列表:

  • B字节
  • C – char
  • D – 双倍
  • F – 浮动
  • – int
  • J – 长
  • L ***完全合格级* ; ** – 在L和a之间; 是完整的类名,使用/作为包之间的分隔符(例如, Ljava/lang/String;
  • S – 短
  • Z – 布尔值
  • [ – 一个[对于arrays的每个维度
  • (***参数类型* )*** return-type * – 方法签名,例如(I)V ,带有附加的伪类型V for void方法

[B @表示“字节数组”。 其他原始数组类型具有不同的前缀:

 class Test { public static void main(String [] args) { byte[] b = new byte[0]; int[] i = new int[0]; char[] c = new char[0]; long[] l = new long[0]; double[] d = new double[0]; float[] f = new float[0]; short[] s = new short[0]; System.out.println(b); System.out.println(i); System.out.println(c.toString()); System.out.println(l); System.out.println(d); System.out.println(f); System.out.println(s); } } 

打印:

 [B@3e25a5 [I@19821f [C@addbf1 [J@42e816 [D@9304b1 [F@190d11 [S@a90653 

非原始类型包括[L之后的类型名称:

 [Ljava.lang.String;@a90653 [Ljava.lang.Object;@de6ced 

如果要将字节数组的内容打印为hex,这里有一些代码可以帮助您:

 class Test { public static void main(String [] args) { byte[] b = new byte[] { (byte) 0xf3, (byte) 0xf1, (byte) 0x7f }; System.out.println(toHex(b)); } private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray(); public static String toHex(byte[] bytes) { char[] c = new char[bytes.length*2]; int index = 0; for (byte b : bytes) { c[index++] = HEX_DIGITS[(b >> 4) & 0xf]; c[index++] = HEX_DIGITS[b & 0xf]; } return new String(c); } } 

默认的toString()实现是类名,后跟’@’,后跟对象的哈希码(hex)。

反过来,默认的哈希码“通常通过将对象的内部地址转换为整数来实现”。 实际上,Sun JVM使用对象句柄的地址作为输入来生成默认哈希码。

在基本类型( intchar等)或数组类型(如byte[] ,使用Java虚拟机规范中为字段描述符定义的命名规则。 根据这些规则,一个'[‘表示一个维度的数组,而’B’表示一个组件类型的byte

我怀疑,虽然我不知道,hex字符串是内存中实例地址的表示,并且可能与数组的长度没什么关系。 你能澄清一下你的问题吗?

值得注意的是equals()来自Object,所以如果a.equals(b)然后a == bie如果你有两个包含相同数据的字节数组,它们不是equals()并且不匹配a中的键Hashtable,HashXxxx