Java: синтаксис и значение, стоящее за "[B @ 1ef9157"? Binary / адрес? - PullRequest
24 голосов
/ 25 июня 2009

Привет, Я пытаюсь выяснить, что означает префикс [B @ в java. Они появляются, когда я пытаюсь напечатать байтовые массивы. Однако байтовые массивы размером 32 и размером 4 идентичны по длине. Всегда "[@ B1234567".

Что это? Кроме того, они имеют свойство только печатать шестнадцатеричные значения. Я знаю, что это не может быть просто двоичный отпечаток, потому что появятся случайные расширенные символы ascii.

Ниже приведен пример печати отображения хеш-таблицы от байта [] к байту [], где сопоставления разделены двоеточием, а это байтовые массивы 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

Ответы [ 5 ]

41 голосов
/ 25 июня 2009

Вы смотрите на идентификатор объекта, а не на дамп содержимого.

  • [ означает массив.
  • B означает байт.
  • @ отделяет тип от идентификатора.
  • шестнадцатеричные цифры являются идентификатором объекта или хэш-кодом.

Если целью является печать содержимого массива, есть много способов. Например:

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 полный список номенклатуры типов можно найти в документации JNI .

Вот весь список:

  • B - байт
  • C - символ
  • D - двойной
  • F - float
  • I - int
  • J - длинный
  • L *** полностью квалифицированный класс *; ** - между L и ; - полное имя класса с использованием / в качестве разделителя между пакетами (для Например, Ljava/lang/String;)
  • S - короткий
  • Z - логическое значение
  • [ - один [ для каждого измерения массива
  • (*** типы аргументов *) *** return-type * - подпись метода, такая как (I)V, с дополнительным псевдотипом V для пустого метода
4 голосов
/ 25 июня 2009

[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

Если вы хотите напечатать содержимое байтового массива в шестнадцатеричном виде, вот код, который вам поможет:

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);
    }
}
2 голосов
/ 25 июня 2009

Реализацией toString() по умолчанию является имя класса, за которым следует '@', за которым следует хеш-код объекта (в шестнадцатеричном формате).

Хэш-код по умолчанию, в свою очередь, «обычно реализуется путем преобразования внутреннего адреса объекта в целое число». На практике Sun JVM использует адрес дескриптора объекта в качестве входных данных для генерации хэш-кода по умолчанию.

В случае примитивных типов (int, char и т. Д.) Или типов массивов, таких как byte[], используются правила именования, определенные в Спецификации виртуальной машины Java для дескрипторов полей. Согласно этим правилам, один «[» обозначает массив одного измерения, а «B» обозначает тип компонента byte.

1 голос
/ 25 июня 2009

Я подозреваю, хотя я не знаю, что шестнадцатеричные строки представляют собой представления адресов экземпляров в памяти и, вероятно, имеют мало общего с длинами массивов. Вы можете уточнить свой вопрос?

0 голосов
/ 25 июня 2009

Стоит отметить, что equals () происходит от Object, так что если a.equals (b), то a == b. т.е. если у вас есть два байтовых массива, которые содержат одинаковые данные, они не равны () и не будут совпадать с ключами в Hashtable, HashXxxx

...