Hey, I'm trying to figure out what the [B@ prefix means in java. They come out when I attempt to print byte arrays. However, byte arrays of size 32 and size 4 are identical in length. Always "[@B1234567".
What is this? Also, they have the property of only printing hex values. I know it can't just be a binary print because random extended ascii chars would appear.
Here is an example of a byte[] to byte[] hashtable mapping print, where mappings are separated by a colon, and these are byte arrays of 4-byte keys and 32-byte elements.
[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
You're looking at the object ID, not a dump of the contents.
If the intent is to print the contents of the array, there are many ways. For example:
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);
}
A complete list of the type nomenclature can be found in the JNI documentation.
Here is the entire list:
L
and a ;
is the full class name, using /
as the delimiter between packages (for example, Ljava/lang/String;
)[
for every dimension of the array(I)V
, with the additional pseudo-type of V
for void method[B@ means "byte array". Other primitive array types have different prefixes:
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);
}
}
Prints:
[B@3e25a5
[I@19821f
[C@addbf1
[J@42e816
[D@9304b1
[F@190d11
[S@a90653
Non-primitive types include the type name after [L
for instance:
[Ljava.lang.String;@a90653
[Ljava.lang.Object;@de6ced
If you want to print the contents of a byte array as hex, here's some code to help you:
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);
}
}
The default toString()
implementation is the class name, followed by '@', followed by the object's hash code (in hexadecimal).
The default hash code, in turn, is "typically implemented by converting the internal address of the object into an integer". In practice, the Sun JVM uses the address of an object handle as input to generate the default hash code.
In the case of primitive types (int
, char
, etc.) or array types like byte[]
, naming rules defined in the Java Virtual Machine Specification for field descriptors are used. According to those rules, one '[' indicates an array of one dimension, while 'B' indicates a component type of byte
.
I suspect, though I don't know, that the hex strings are representations of the instances' addresses in memory, and probably have little to do with the lengths of the arrays. Can you clarify your question?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With