Back to Java
2026-05-136 min read

Typed Reference (Java)

Learn Typed Reference (Java) step by step with clear examples and exercises.

Title: Typed Reference (Java) - Mastering Java's Advanced Data Types

Why This Matters

In this lesson, we will delve into one of the most powerful features of Java - Typed References. Understanding typed references is crucial for writing efficient and effective code in Java, especially when dealing with complex data structures. It plays a significant role in interviews, real-world programming scenarios, and debugging common pitfalls.

Prerequisites

Before diving into the core concept of typed references, it's essential to have a solid understanding of the following:

  1. Basic Java syntax (variables, operators, control structures)
  2. Data structures (arrays, lists, and maps)
  3. Object-oriented programming concepts (classes, objects, inheritance, and interfaces)
  4. Exception handling in Java
  5. Understanding of memory management in Java
  6. Familiarity with basic Java classes such as String, Integer, and Double
  7. Understanding the difference between primitive types and reference types
  8. Understanding constructors, getters, and setters in Java
  9. Knowledge of interfaces and abstract classes
  10. Familiarity with Java's collection framework (ArrayList, LinkedList, HashMap, etc.)

Core Concept

Typed references in Java are a way to manage data using object-oriented principles. They allow us to create variables that hold objects of specific classes, ensuring type safety and enabling polymorphism. In this lesson, we will focus on three main types of typed references:

  1. Reference Variables
  2. Arrays
  3. Generics
  4. Interfaces and Abstract Classes (optional but recommended for a more in-depth understanding)

Reference Variables

A reference variable is a variable that stores the memory address of an object instance. It can be declared using any valid Java identifier and data type (class name). Here's an example:

// Declaring a reference variable for a Dog class
Dog myPet;

In this example, myPet is a reference variable that can hold the memory address of an object instance of the Dog class.

Arrays

An array in Java is a collection of variables of the same data type. When we create an array, we are essentially creating multiple reference variables of the same data type. Here's an example:

// Declaring an array of Dog objects
Dog[] dogs;

In this example, dogs is an array that can hold multiple memory addresses (references) of Dog objects.

Generics

Generics in Java allow us to create classes and methods that work with multiple data types while maintaining type safety at compile time. Here's an example:

// Declaring a generic List class for storing objects of any type
public class MyList<T> {
private T[] elements;

// Constructor, getters, setters, and other methods go here...
}

In this example, MyList is a generic class that can store objects of any data type (specified by the type parameter T) while ensuring type safety at compile time.

Interfaces and Abstract Classes

Interfaces define a contract for a set of methods that a class implementing the interface must provide. Abstract classes are incomplete classes that cannot be instantiated but can be extended by other classes. Both interfaces and abstract classes play a crucial role in polymorphism, which allows us to treat different objects as if they were of the same type.

Worked Example

Let's create a simple program demonstrating the use of typed references:

public class Main {
public static void main(String[] args) {
// Creating a Dog object and assigning it to a reference variable
Dog myPet = new Dog("Fido");

// Printing the name of the dog using the reference variable
System.out.println(myPet.getName());

// Creating an array of Dog objects
Dog[] dogs = {new Dog("Buddy"), new Dog("Max")};

// Iterating through the array and printing the names of the dogs
for (int i = 0; i < dogs.length; i++) {
System.out.println(dogs[i].getName());
}

// Creating a generic MyList object to store Dog objects
MyList<Dog> myPets = new MyList<>();
myPets.add(new Dog("Rex"));
myPets.add(myPet);

// Iterating through the MyList and printing the names of the dogs
for (int i = 0; i < myPets.size(); i++) {
System.out.println(myPets.get(i).getName());
}

// Creating a generic MyList object to store Animal objects (with a common interface)
MyList<Animal> animals = new MyList<>();
animals.add(new Dog("Rex"));
animals.add(new Cat("Whiskers"));

// Iterating through the MyList and printing the names of the animals
for (int i = 0; i < animals.size(); i++) {
System.out.println(animals.get(i).getName());
}
}

// Animal interface definition goes here...

// Dog class definition goes here...
}

Common Mistakes

  1. Forgetting to initialize reference variables: Always ensure that you assign an object instance to a reference variable before using it, or set it to null.
  1. Using raw types in arrays and generic classes: Avoid using raw types (e.g., ArrayList or MyList[]) as they compromise type safety.
  1. Not understanding the difference between primitive types and reference types: Primitive types like int, char, and boolean are not objects, so they cannot be used with typed references.
  1. Assuming that primitive values can be directly assigned to reference variables or arrays of reference variables: Primitive values must be wrapped in appropriate wrapper classes (e.g., Integer, Double) before being assigned.
  1. Not understanding the concept of nullable types and non-nullable types in Java 14+: Nullable types allow for null values, while non-nullable types do not. Properly managing nullability can help prevent NullPointerExceptions.
  1. Not properly implementing abstract methods in classes that extend an abstract class or implement an interface: All abstract methods must be implemented in the concrete class.
  1. Not understanding the difference between interfaces and abstract classes: Interfaces define a contract for a set of methods, while abstract classes provide a partially implemented class that can be extended by other classes.

Practice Questions

  1. Write a program that creates an array of Circle objects (each with a radius) and calculates the total area of all circles in the array.
  1. Create a generic Queue class using Java's built-in LinkedList to store Integer objects. Implement methods for enqueue, dequeue, and peek operations.
  1. Write a program that demonstrates the use of nullable and non-nullable types in Java 14+.
  1. Create an abstract class Animal with methods eat(), sleep(), and move(). Create two concrete classes Dog and Cat that extend the Animal class and provide their own implementations for these methods.
  1. Write a program that creates an array of Shape objects (each implementing the Draw interface) and calls the draw() method on each shape.

FAQ

  1. Why should I use typed references instead of primitive types?
  • Typed references allow for more flexibility, as they can hold object instances with multiple properties and behaviors. Primitive types are limited to a single value and no methods.
  1. What happens if I try to assign a primitive type to a reference variable or an array of reference variables?
  • The primitive value will be automatically boxed (wrapped in an object) before being assigned, but unboxing should be done explicitly using the intValue(), charValue(), etc., methods.
  1. Can I create a generic class that can store objects of different data types?
  • Yes, you can use Java's Object type as the type parameter for a generic class to achieve this, but it compromises type safety at runtime. A better approach is to use a common interface shared by all the classes you want to store in your generic class.
  1. What are nullable and non-nullable types in Java 14+?
  • Nullable types allow for null values, while non-nullable types do not. Properly managing nullability can help prevent NullPointerExceptions.
  1. How can I create a generic class that can store objects of different data types without using raw types?
  • You can use Java's Object type as the type parameter for a generic class to achieve this, but it compromises type safety at runtime. A better approach is to use a common interface shared by all the classes you want to store in your generic class.
  1. What is the difference between interfaces and abstract classes?
  • Interfaces define a contract for a set of methods that a class implementing the interface must provide, while abstract classes provide a partially implemented class that can be extended by other classes.
  1. Why should I use interfaces or abstract classes in my code?
  • Using interfaces and abstract classes allows for polymorphism, which enables us to treat different objects as if they were of the same type, making our code more flexible and reusable.
Typed Reference (Java) | Java | XQA Learn