Accessing Objects via Reference Variables
Tags: java, programming, learning, beginners
Published: 2024-06-03 17:57:30

An object’s data and methods can be accessed through the dot (**.**) operator via the object’s reference variable. Newly created objects are allocated in the memory. They can be accessed via reference variables.

## Reference Variables and Reference Types

Objects are accessed via the object’s _reference variables_, which contain references to the objects. Such variables are declared using the following syntax:

`ClassName objectRefVar;`

A class is essentially a programmer-defined type. A class is a _reference type_, which means that a variable of the class type can reference an instance of the class. The following statement declares the variable **myCircle** to be of the **Circle** type:

`Circle myCircle;`

The variable **myCircle** can reference a **Circle** object. The next statement creates an object and assigns its reference to **myCircle**:

`myCircle = new Circle();`

You can write a single statement that combines the declaration of an object reference variable, the creation of an object, and the assigning of an object reference to the variable with the following syntax:

`ClassName objectRefVar = new ClassName();`

Here is an example:

`Circle myCircle = new Circle();`

The variable **myCircle** holds a reference to a **Circle** object.

An object reference variable that appears to hold an object actually contains a reference to that object. Strictly speaking, an object reference variable and an object are different, but most of the time the distinction can be ignored. Therefore, it is fine, for simplicity, to
say that **myCircle** is a **Circle** object rather than use the longer-winded description that **myCircle** is a variable that contains a reference to a **Circle** object.

Arrays are treated as objects in Java. Arrays are created using the **new** operator. An array variable is actually a variable that contains a reference to an array.

## Accessing an Object’s Data and Methods

In OOP terminology, an object’s member refers to its data fields and methods. After an object is created, its data can be accessed and its methods can be invoked using the _dot operator_ (**.**), also known as the _object member access operator_:

- **objectRefVar.dataField** references a data field in the object.
- **objectRefVar.method(arguments)** invokes a method on the object.

For example, **myCircle.radius** references the radius in **myCircle**, and **myCircle.getArea()** invokes the **getArea** method on **myCircle**. Methods are invoked as operations on objects.

The data field **radius** is referred to as an _instance variable_, because it is dependent on a specific instance. For the same reason, the method **getArea** is referred to as an _instance method_, because you can invoke it only on a specific instance. The object on which an instance method is invoked is called a _calling object_.

Recall that you use **Math.methodName(arguments)** (e.g., **Math.pow(3, 2.5)**) to invoke a method in the **Math** class. Can you invoke **getArea()** using **Circle.getArea()**? The answer is no. All the methods in the **Math** class are static methods, which are defined using the **static** keyword. However, **getArea()** is an instance method, and thus nonstatic. It must be invoked from an object using **objectRefVar.methodName(arguments)** (e.g., **myCircle.getArea()**). 

Usually you create an object and assign it to a variable, and then later you can use the variable to reference the object. Occasionally an object does not need to be referenced later. In this case, you can create an object without explicitly assigning it to a variable using the syntax:

`new Circle();`

or

`System.out.println("Area is " + new Circle(5).getArea());`

The former statement creates a **Circle** object. The latter creates a **Circle** object and invokes its **getArea** method to return its area. An object created in this way is known as an _anonymous object_.

## Reference Data Fields and the null Value

The data fields can be of reference types. For example, the following **Student** class contains a data field **name** of the **String** type. **String** is a predefined Java class.

`class Student {
 String name; // name has the default value null
int age; // age has the default value 0
boolean isScienceMajor; // isScienceMajor has default value false
char gender; // gender has default value '\u0000'
}`

If a data field of a reference type does not reference any object, the data field holds a special Java value, **null**. **null** is a literal just like **true** and **false**. While **true** and **false** are Boolean literals, **null** is a literal for a reference type.

The default value of a data field is **null** for a reference type, **0** for a numeric type, **false** for a **boolean** type, and **\u0000** for a **char** type. However, Java assigns no default value to a local variable inside a method. The following code displays the default values of the data fields **name**, **age**, **isScienceMajor**, and **gender** for a **Student** object:

`class Test {
public static void main(String[] args) {
Student student = new Student();
 System.out.println("name? " + student.name);
 System.out.println("age? " + student.age);
 System.out.println("isScienceMajor? " + student.isScienceMajor);
 System.out.println("gender? " + student.gender);
 }
}`

The following code has a compile error, because the local variables **x** and **y** are not initialized:

`class Test {
public static void main(String[] args) {
int x; // x has no default value
String y; // y has no default value
 System.out.println("x is " + x);
 System.out.println("y is " + y);
 }
}`

**NullPointerException** is a common runtime error. It occurs when you invoke a method on a reference variable with a **null** value.

## Differences between Variables of Primitive Types and Reference Types

Every variable represents a memory location that holds a value. When you declare a variable, you are telling the compiler what type of value the variable can hold. For a variable of a primitive type, the value is of the primitive type. For a variable of a reference type, the value is a
reference to where an object is located. For example, as shown in Figure below, the value of **int** variable **i** is **int** value **1**, and the value of **Circle** object **c** holds a reference to where the contents of the **Circle** object are stored in memory.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/txkr37cepzvbh9zsxbjc.png)

When you assign one variable to another, the other variable is set to the same value. For a variable of a primitive type, the real value of one variable is assigned to the other variable. For a variable of a reference type, the reference of one variable is assigned to the other variable.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okacy9yqn522klsn9ylv.png)

As shown in Figure above, the assignment statement **i = j** copies the contents of **j** into **i** for primitive variables. As shown in Figure below, the assignment statement **c1 = c2** copies the reference of **c2** into **c1** for reference variables. After the assignment, variables **c1** and **c2** refer to the same object.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bamjppn60pac71q67jtn.png)

After the assignment statement **c1 = c2**, **c1** points to the same object referenced by **c2**. The object previously referenced by **c1** is no longer useful and therefore is now known as _garbage_. Garbage occupies memory space, so the Java runtime system detects garbage and automatically reclaims the space it occupies. This process is called _garbage collection_.

If you know that an object is no longer needed, you can explicitly assign **null** to a reference variable for the object. The JVM will automatically collect the space if the object is not referenced by any reference variable.