Hello, Amigo! I'd like to tell you about the internal structure of variables. As you already know, each variable is associated with an area of memory where its value is stored."

"Yes. You told me about that last time."

"Great. It's good that you remember. I'll go on, then."

"All composite types consist of simpler ones. And they, in their turn, consist of even simpler ones. Until, at last, we end up with primitive types, which cannot be further simplified. That's what they are called – primitive types. For example, int is a primitive type, but String is a composite type that stores its data as a table of characters (where each character is a primitive type char)."

"Very interesting. Go on."

"Composite types are formed by grouping simple ones. We call such types classes. When we define a new class in a program, we declare a new composite data type. Its data will be either other composite types or primitive types."

Java code Description
public class Person
   String name;
   int age;
A new composite type is declared – Person.
Its data is stored in the String (composite type) variable name and int (primitive type) variable age
public class Rectangle
   int x, y, width, height;
A new composite type is declared – Rectangle.
It consists of four int (primitive type) variables.
public class Cat
   Person owner;
   Rectangle territory;
   int age;
   String name;
A new composite type is declared – Cat. It has the following variables:
owner, composite type Person
territory, composite type Rectangle
age, primitive type int
name, composite type String

"For now, everything is clear, however weird it may seem."

"Big (composite) types contain many small (primitive) types. That's why objects of these types take up a lot of memory - more than variables of the primitive types. Sometimes much more. Performing assignment operations with such variables used to take a long time and required the copying of large sections of memory. That's why variables of composite types do not store the object itself, but rather just a reference to it, i.e. its four-byte address. This is enough to address the data in such objects. The Java machine handles all the associated complexities."

"I didn't understand any of that."

"We've previously said that a variable is like a box. If you want to store the number 13 in it, you can write 13 on a piece of paper and put it into the box."

"But imagine that you need to store something bigger in the box (variable). For example, a dog, a car, or your neighbor. Instead of trying to push the unpushable into the box, you could do something easier: use a photo of the dog instead of the actual dog, a license plate instead of a real car, or your neighbor's phone number instead of your neighbor."

"We take a piece of paper and write down the neighbor's phone number. This is like a reference to an object. If we copy the piece of paper with the neighbor's phone number on it and put it in several boxes, there are now more references to your neighbor. But, as before, you still have just one neighbor. That makes sense, doesn't it?"

"An important feature of storing data in this way is that you can have many references to a single object"

"How interesting! I've almost got it. Tell me one more time, please – what would happen if I assign a variable of a composite type to another variable of the same composite type?"

"Then the two variables would store the same address. That means that if you change the data of the object referenced by one variable, you change the data referenced by the other. Both variables reference the same object. Of course, there may be many other variables that also store references to it."

"What do variables of composite (reference/class) types do if they aren't holding a reference to an object? Is that even possible?"

"Yes, Amigo. You're getting ahead of me with your question. That is possible. If a variable of a reference (composite) type isn't storing a reference to an object, then it stores what is known as a 'null reference'. Basically, this means that it references an object whose address is 0. However, the Java machine never creates objects with this address, so it always knows that if a reference variable contains 0, then it isn't pointing to any object."

Java code Description
String s;
String s = null;
Equivalent statements.
Person person;
person = new Person();
person = null;
We create a person variable whose value is null.
We assign to it the address of a newly created Person object.
We assign null to the variable.
Cat cat = new Cat();
cat.owner = new Person();
cat.owner.name = "God";
We create a Cat object and store its address in variable cat; cat.owner equals null.
We set cat.owner equal to the address of a newly created Person object.
cat.owner.name still equals null.
We set cat.owner.name equal to "God"

"Did I understand you correctly? Variables are divided into two types: primitive types and reference types. Primitive types store values directly, while reference types store a reference to an object. Primitive types include int, char, boolean, and many others. Reference types include everything else. We use classes to create them."

"You're absolutely right, my boy."

"So, you say you've understood everything. Here are some tasks to help you reinforce your knowledge."