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();