Reading byte array into float (expanding on SerialCallResponse example)

We use the dot . access operator right after a reference in order to access 1 of its members:

Therefore we need to know the available members we can access from a reference before we can use the dot . operator on it.

Let’s examine the expression ByteBuffer.wrap(bytes).asFloatBuffer() which is immediately assigned to declared field FloatBuffer buf.

ByteBuffer is a class reference:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/ByteBuffer.html

B/c it is a class, and not an object derived from it (instance), we can only access static members from it via the dot . operator.

So we invoke its public static member method wrap() via the dot . operator:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/ByteBuffer.html#wrap(byte[])

According to that method’s doc, it says it returns a new ByteBuffer object.

So the 2nd dot . operator acts upon what is returned by method wrap(), which is an instance of ByteBuffer, allowing us to access its non-static members as well.

So now we invoke its instance method asFloatBuffer():
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/ByteBuffer.html#asFloatBuffer()

Which states it returns a new FloatBuffer object:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/FloatBuffer.html

We stop chaining dot . operators; and that last returned reference (AKA memory address or pointer) is finally assigned to field buf of datatype FloatBuffer:
FloatBuffer buf = ByteBuffer.wrap(bytes).asFloatBuffer();

As you can see from its Java doc link above, FloatBuffer is an abstract class that lacks a formal public constructor.

Although we can also get an instance of it via its static methods like allocate() & wrap():
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/FloatBuffer.html#allocate(int)
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/FloatBuffer.html#wrap(float[])

However, its static method wrap() accepts a float[] array only.

But we really need to pass a byte[] array b/c method Serial::readBytes() doesn’t work w/ float[]:

That’s why we had to indirectly get an instance of it via method ByteBuffer::asFloatBuffer().

Now let’s check the statement: buf.get(floats).rewind();

We use the dot . operator in order to invoke method FloatBuffer::get() over field buf, which stores the reference of a FloatBuffer object:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/FloatBuffer.html#get(float[])

That method informs us that it returns a FloatBuffer as “This buffer”.

It means it’s not a new instance but the same object that had been used to invoke it.

That is, the very reference stored in our field buf.

Such methods are said to be chainable, b/c they return itself, allowing us to keep on accessing members of the same reference in sequence via multiple dot . usage.

So the 2nd dot . operator invokes method rewind() over the same buf:
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/nio/Buffer.html#rewind()

Notice though method rewind() comes from its superclass Buffer.

Obviously, we coulda split the expression in 2:

buf.get(floats);
buf.rewind();
2 Likes