-2

When converting a ByteBuffer to an int array java unexpectedly throws an UnsupportedOperationException.

However as a byte array the information is correctly represented.

int[] intArray = new int[]{1, 2};
ByteBuffer byteBuffer = ByteBuffer.allocate(intArray.length * 4);
IntBuffer ib = byteBuffer.asIntBuffer();
ib.put(intArray);
System.out.println(Arrays.toString(byteBuffer.array())); // prints [0, 0, 0, 1, 0, 0, 0, 2]
System.out.println(Arrays.toString(ib.array())); // Fails with exception UnsupportedOperationException

Reading through other posts I saw this exception in case there was no array to back up the ByteBuffer, but in this case the buffer has enough bytes allocated and should be able to return an int[].

Why is this exception thrown?

(Using java11)

Seb
  • 1,586
  • 1
  • 11
  • 15
  • Please check that answer https://stackoverflow.com/a/19624671/13523946 – notAPPP Sep 21 '22 at 21:56
  • “…should be able to return an `int[]`.” You seem to be under the impression that the `array()` method *converts* the buffer’s contents to an array, like Collection.toArray or Stream.toArray, but that is not the case. As Slaw explained, it returns the array that directly backs the buffer; if the buffer wasn’t created directly from an int array, you get an UnsupportedOpertaionException. – VGR Sep 21 '22 at 23:42
  • But how would it be possible to transform a Bytebuffer into an int array without allocating new memory? – Seb Sep 23 '22 at 20:04
  • It's not possible to transform a `ByteBuffer` to an `int[]` without allocating new memory for the `int[]`. The best you could do is make use of the `IntBuffer` you created via `#asIntBuffer()`. Obviously, that allocates memory for the `IntBuffer` instance, but both the `ByteBuffer` and the `IntBuffer` will be backed by the same `byte[]` instance. – Slaw Sep 25 '22 at 08:06

1 Answers1

1

The #array() methods of all the buffer classes are defined to throw UnsupportedOperationException:

If this buffer is not backed by an accessible array

Also, modifying the array returned by #array() modifies the buffer:

Modifications to this buffer's content will cause the returned array's content to be modified, and vice versa.

And you're calling it on an IntBuffer that was created via ByteBuffer#asIntBuffer(), which:

Creates a view [emphasis added] of this byte buffer as an int buffer.

The content of the new buffer will start at this buffer's current position. Changes to this buffer's content will be visible in the new buffer, and vice versa [emphasis added]; the two buffers' position, limit, and mark values will be independent.

[...]

Combine all that information and you can see why calling array() on your IntBuffer throws an UnsupportedOperationException. If it were to return an int[], then changing the int[] would not be capable of modifying the ByteBuffer. This is a problem, because modifying the int[] is defined to modify the IntBuffer, and since your IntBuffer is only a view, modifying the IntBuffer is defined to also modify the ByteBuffer. But it's not possible to directly "link" a byte[] and an int[], hence the operation is not supported.

Slaw
  • 37,820
  • 8
  • 53
  • 80