Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a single reference variable access to all object fields?

Tags:

java

jvm

Animal myAnimal = new Animal();

I have this code above. As far as I know, it will do these things :

  1. An animal object will be created on heap memory
  2. The reference to that object will be passed to the reference variable "myAnimal" In other words, "myAnimal" variable holds the memory address of "Animal" object on heap.

What I don't understand is that

  1. How does the memory address value look like?
  2. Is that one address or numerous address value? If only one, how can myAnimal have accesses to all object fields of Animal object like myAnimal.name, myAnimal.height,...?

Can anyone explain this please? Thanks in advance.

like image 329
Bonsaisteak Avatar asked Dec 18 '22 00:12

Bonsaisteak


2 Answers

This is an oversimplification:

  1. It's just a number that represents some address location; how big that number is depends on your computer's architecture (32 bit or 64 bit)

  2. It is one address value; it is the address location of the place where your object representation in memory starts.

You can compare it with the address of your house. It has one address. All rooms in your house (fields) have a different location, but you have to enter through your front door (the 'start' location). Room locations are relative to your front door. I admit this example is a bit contrived, but you get the point...

like image 88
Wim Bokkers Avatar answered May 23 '23 23:05

Wim Bokkers


The Java Virtual Machine Specification states

There are three kinds of reference types: class types, array types, and interface types. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively.

and clarifies

Values of type reference can be thought of as pointers to objects.

So the variable myAnimal in

Animal myAnimal = new Animal();

is storing a pointer to the Animal object on the heap.

You ask

How does the memory address value look like?

A memory address is typically just a numerical value that's an offset into the process' allocated memory. When a process reads that value, it can directly address that location and read from or write to it (think of it as an offset index in an array).

The object itself is more than just its address. In fact, its address can change multiple times over the lifetime of the JVM process as the garbage collector moves objects around.

However, the JVMS does not specify the internal structure of an object.

The Java Virtual Machine does not mandate any particular internal structure for objects.

In some of Oracle’s implementations of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.

This doesn't help greatly, but we can assume that the memory allocated for the object data has to be large enough to contain all the object's fields and the data needs to be accessible quickly, ie. in constant time, as opposed to proportionally to the amount of data. The typical solution is to again use offsets. Take this class for example

class Animal {
    private String name;
    private byte height;
}

The field name is of type String, a reference type, which we know essentially just stores a pointer. If we assume our JVM only needs 32 bits to store a pointer, we know we only need 32 bits for this field.

The field height is of type byte, which is specified to only need 8 bits.

So each Person object really only needs 32+8 bits, 5 bytes for its data. The JVM will most likely allocate more than that for its internal organization, but let's simplify to just those 5 bytes. In your example, the JVM will allocate the first 4 bytes for the name and the next byte for the age. Something like

 0        8       16       24       32       40
 +--------+--------+--------+--------+--------+
 |               name                | height |

You ask

Is that one address or numerous address value? If only one, how can myAnimal have accesses to all object fields of Animal object like myAnimal.name, myAnimal.height,...?

myAnimal holds only one address, but an expression like

myAnimal.height

can be thought of as reading 1 byte (because we know height is of type byte) from memory at the address determined by adding 4 (because the location of the data for height is offset by the 4 bytes needed for name) to the value stored in myAnimal.

Consider myAnimal storing a pointer to a memory address of 12, initialized with a name pointing to a String at memory address 1345 and a height value of 6. In memory, that could look like

                   myAnimal
                      |
                      v
Heap:             ...12.......13.......14.......15.......16.......17
Object offsets:   ....0        1        2        3        4        5
                  ....+--------+--------+--------+--------+--------+ 
                      |               1345                |    6   | 

To read myAnimal.height, the JVM would calculate 12 + 4 = 16 and read the byte (6) at that offset. To assign a new value to myAnimal.name, the JVM would calculate 12 + 0, and write 4 bytes representing some the new pointer value, overwriting the 1345.

like image 44
Savior Avatar answered May 23 '23 21:05

Savior