In the previous article, Java Data and Data Types, common data types are introduced. Programmers use these types to define variables to track states of a program (for example, car speed). In this article, we study Java data types in more detail and explain two broad categories in Java’s type system, primitive and references types, and how they are represented in memory.
This is a very fundamental topic in Java and paramount in learning Java.
Most of the types mentioned in the previous article types are primitive types, which are the most basic data types in java. Primitive types are:
Primitive types also have the properties that they are fixed sized, such that all variable of the same type use the same amount of memory, and “indivisible”, such that they are not composed of other types.
Conceptually, computer memory is a set of storage cells, each with an address. For example, the figure below shows a block of memory with address from
When a variable of a primitive type is declared,
int myInt = 10; for example, this variable represents a memory location. In the figure below,
myInt represent memory location
102 and we can use
myInt to store to and read from this memory location. In addition, when the program is compiled, all occurrences of
myInt is replaced with memory address
102. For example, when we write the statement
myInt = 10;, it literally means, set the content of memory location
102 to integer
Reference types are any class types and arrays. These include the
String class, and any class you write. The reason that these are called reference types is because, in contrast to primitive types, a variable (memory location) of this type holds a memory address to the data, instead of the data itself. We give an example below.
Let’s say we have this statement in our program:
String s = "Hello";
What this statement does is assign a memory location to
s, but the location does not store the string
"Hello", but the address of it, as shown in the figure below. In the figure,
s represents memory address
101. However, at this location, the location of the string
"Hello" is stored which is at location
Also note that objects (the actual data) may take more than 1 memory locations. In fact, some data may take many memory locations (use lots of memory) as in a long array. One justification for storing references instead of the actual data is that since the compiler does not know how large the actual data will be when the program is executed, JVM has to find a memory location large enough for the data during runtime.
In the following code snippet, we are not copying the content of
b, but only copying the address.
Instantiation mean to create an object from a class. For example, the following code performs two instantiations: one of
String and one of
Each of above actually take two steps. The first step is declaration, where a variable of the desired type is declared. The second step is the actual instantiation, where the object is created, as shown below.
After the first step (and before the second step) is performed, the variable
p holds the value of
null, which is a special value that can be assigned to variables of references types and means the variable does not point to any object. If we call any method or field of this variable at this point, we will get the error
The second step does the following:
- Ask Java to find a block of memory large enough for the Person object
- Create the object
- Return the address of the object
- Put the address in varaible p
After the second step, methods of the object can be safely called.
Object of Other Objects
Often we have objects that are composed of other objects. For example, in the following code, we have a
Person class, which contains another object of type String. The following figure shows how an object of Person class is presented in memory, when a variable,
p, is declared.
Note that arrays are also reference types. The following figure shows how an array of objects are stored.