ByteBuffer getInt () вопрос

мы используем Java ByteBuffer для связи сокетов с сервером C++. Мы знаем, что Java является Big-endian и сокет связи также Big-endian. Поэтому всякий раз, когда поток байтов получен и помещен в ByteBuffer Java, мы вызываем getInt (), чтобы получить значение. Никаких проблем, никакого обращения.

но если каким-то образом мы специально установили порядок байтов ByteBuffer в Little-endian (мой коллега действительно сделал это),

  1. Java автоматически преобразует Тупоконечниками в младший разряд, когда данные в ByteBuffer?

  2. тогда getInt () версии Little-endian вернет вам правильное значение?

Я думаю, что ответ на два вышеуказанных вопроса-да. Но когда я пытаюсь проверить свои догадки и попытаться найти, как работает getInt() в ByteBuffer, я обнаружил, что это абстрактный метод. Единственным подклассом ByteBuffer является класс MappedByteBuffer, который не реализовал абстрактное getInt (). Итак, где же реализация метода getInt ()?

для отправки, потому что мы используем Little-endian ByteBuffer, нам нужно преобразовать их в байты Big-endian, прежде чем мы поместим в сокет.

2 ответов


Итак, где же реализация метода getInt ()?

ByteBuffer действительно абстрактный класс. Существует несколько способов создания байтовых буферов:

в моем JDK они создают экземпляры внутренних классов HeapByteBuffer и DirectByteBuffer. Их getInt функции следующим образом:

// HeapByteBuffer

public int getInt() {
    return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
}

public int getInt(int i) {
    return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
}

и

// DirectByteBuffer

private int getInt(long a) {
    if (unaligned) {
        int x = unsafe.getInt(a);
        return (nativeByteOrder ? x : Bits.swap(x));
    }
    return Bits.getInt(a, bigEndian);
}

public int getInt() {
    return getInt(ix(nextGetIndex((1 << 2))));
}

public int getInt(int i) {
    return getInt(ix(checkIndex(i, (1 << 2))));
}

выше nativeByteOrder и bigEndian являются двумя логическими членами, указывающими соответственно - и несколько избыточно - соответствует ли настроенный порядок байтов: (a) собственному порядку байтов; (b) является большим эндианом.


ByteBuffer будет автоматически использовать указанный вами порядок байтов. (Или Big endian по умолчанию)

 ByteBuffer bb =
 // to use big endian
 bb.order(ByteOrder.BIG_ENDIAN);

 // to use little endian
 bb.order(ByteOrder.LITTLE_ENDIAN);

 // use the natural order of the system.
 bb.order(ByteOrder.nativeOrder()); 

как direct, так и heap ByteBuffers будут переупорядочивать байты, как вы указываете.