Back to Java
2026-04-226 min read

Non-primitive Types (Java)

Learn Non-primitive Types (Java) step by step with clear examples and exercises.

Why This Matters

Understanding non-primitive data types is crucial for mastering Java programming. Non-primitive types allow us to work with complex data structures like arrays, strings, and custom objects, enabling the creation of more sophisticated programs and efficient problem-solving. By learning how to effectively use these data types, you will be better equipped to tackle real-world programming challenges.

Prerequisites

Before diving into this lesson, it's essential that you have a solid understanding of:

  1. Java syntax and variables (primitive data types)
  2. Basic control structures (if-else, loops)
  3. Object-Oriented Programming (OOP) concepts (classes, methods, inheritance, polymorphism)
  4. Exception handling
  5. File I/O operations
  6. Understanding the Java Virtual Machine (JVM) and memory management
  7. Basic understanding of data structures and algorithms
  8. Familiarity with Java's standard library classes and interfaces

Core Concept

Definition

In Java, non-primitive data types are reference types that consist of classes and interfaces. Unlike primitive data types, they occupy memory locations on the heap rather than the stack. This means they can hold references to multiple variables or objects.

Classes

A class is a blueprint for creating objects (instances) in Java. It defines a set of properties (attributes or fields) and behaviors (methods). Here's an example of a simple class:

public class Book {
private String title;
private String author;
private int publicationYear;
private double price;

// Constructor
public Book(String title, String author, int publicationYear, double price) {
this.title = title;
this.author = author;
this.publicationYear = publicationYear;
this.price = price;
}

// Getters and Setters
public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public int getPublicationYear() {
return publicationYear;
}

public void setPublicationYear(int publicationYear) {
this.publicationYear = publicationYear;
}

public double getPrice() {
return price;
}

public void setPrice(double price) {
this.price = price;
}
}

Arrays

An array is a collection of elements of the same data type. To create an array, you first define its data type and then allocate memory for it using new. Here's an example:

int[] numbers = new int[5];
numbers[0] = 1; // Assign values to each element

Strings

A String in Java is a sequence of characters treated as a single unit. Strings are immutable, meaning once created, their value cannot be changed. However, you can create new strings by concatenating existing ones or using the substring(), replace(), and other methods provided by the String class. Here's an example:

String myString = "Hello, World!";
System.out.println(myString.toUpperCase()); // Output: HELLO, WORLD!

Custom Objects

Creating custom objects involves defining a class and then creating instances of that class using the new keyword. Here's an example:

Book book1 = new Book("The Catcher in the Rye", "J.D. Salinger", 1951, 20.0);

Lists and Maps

Java provides several collections framework classes, such as ArrayList, LinkedList, Vector, HashSet, TreeSet, HashMap, and LinkedHashMap. These classes are essential for managing complex data structures in a more efficient manner.

Worked Example

Let's create a simple program that demonstrates the use of non-primitive data types:

import java.util.*;

public class Main {
public static void main(String[] args) {
// Creating an ArrayList of Books
List<Book> books = new ArrayList<>();
books.add(new Book("The Catcher in the Rye", "J.D. Salinger", 1951, 20.0));
books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960, 15.0));

// Common Mistake 1: Forgetting to initialize arrays or collections
String[] authors = new String[2]; // Initialize the array with the correct size
authors[0] = "J.D. Salinger";
authors[1] = "Harper Lee";

// Creating a HashMap to store authors and their books
Map<String, List<Book>> authorBooks = new HashMap<>();
List<Book> ernestHemingwayBooks = new ArrayList<>();
ernestHemingwayBooks.add(new Book("The Old Man and the Sea", "Ernest Hemingway", 1952, 10.0));
ernestHemingwayBooks.add(new Book("For Whom the Bell Tolls", "Ernest Hemingway", 1940, 18.0));
authorBooks.put("Ernest Hemingway", ernestHemingwayBooks);

// Common Mistake 2: Accessing out-of-bounds array elements or collection indices
String author = authors[3]; // This will cause an ArrayIndexOutOfBoundsException

// Printing books by their authors
for (Map.Entry<String, List<Book>> entry : authorBooks.entrySet()) {
System.out.println(entry.getKey() + "'s Books:");
for (Book book : entry.getValue()) {
System.out.println("- " + book.getTitle());
System.out.println(" - Author: " + book.getAuthor());
System.out.println(" - Publication Year: " + book.getPublicationYear());
System.out.println(" - Price: $" + book.getPrice());
}
}
}
}

Common Mistakes

  1. Forgetting to initialize arrays or collections: Always ensure that you allocate memory for arrays and collections before using them.

Example:

int[] numbers = new int[5]; // Correct initialization
// Instead of:
int[] numbers; // Incorrect initialization
  1. Accessing out-of-bounds array elements or collection indices: Be mindful of the index range when accessing array elements, collection indices, or iterating through collections to avoid ArrayIndexOutOfBoundsException, NoSuchElementException, or other related exceptions.

Example:

String author = authors[3]; // This will cause an ArrayIndexOutOfBoundsException
// Instead of:
for (int i = 0; i < authors.length; i++) {
System.out.println(authors[i]);
}

Practice Questions

  1. Create a class called Person with fields for name, age, gender, and address. Write a constructor that initializes these fields. Add methods for setting and getting each field's value.
  2. Create an ArrayList of Strings containing the names of five famous authors. Iterate through the list and print each author's name.
  3. Write a program that reads user input for the title, author, publication year, and price of a book and creates a Book object using the provided data. Store the book in an ArrayList.
  4. Write a program that reads a list of books from a file (each line contains title, author, publication year, and price) and stores them in an ArrayList of custom Book objects.
  5. Write a program that sorts an ArrayList of Book objects based on their publication years.
  6. Write a program that creates two Person objects representing you and your best friend and prints their names, ages, and genders.
  7. Implement a simple text editor using a HashMap to store lines of text in an ArrayList, allowing users to add, remove, and display lines of text.
  8. Create a custom collection class called PriorityQueue that implements the Queue interface and maintains elements in priority order based on a custom comparison function. Implement methods for adding and removing elements from the queue.
  9. Write a program that reads a list of integers from a file, sorts them using the quicksort algorithm, and writes the sorted list back to the file.
  10. Create a class called Shape with fields for name, color, and area. Implement methods for calculating the area of each shape (e.g., Circle, Rectangle, Triangle). Write a program that creates instances of various shapes, calculates their areas, and stores them in an ArrayList. Finally, print the total area of all shapes.

FAQ

What is the difference between primitive and non-primitive data types in Java?

Answer: Primitive data types occupy memory on the stack, while non-primitive data types occupy memory on the heap. Non-primitive data types can hold references to multiple variables or objects.

How do I create a custom object in Java?

Answer: Creating a custom object involves defining a class and then creating instances of that class using the new keyword.

What is the purpose of getters and setters in Java?

Answer: Getters (accessor methods) allow you to retrieve the value of a private field, while setters (mutator methods) allow you to modify the value of a private field.

How do I create an ArrayList in Java?

Answer: To create an ArrayList, first define its data type and then allocate memory for it using new: List listName = new ArrayList<>();.

What is the difference between a String and a string literal in Java?

Answer: A String is an object that represents a sequence of characters, while a string literal is a series of characters enclosed in double quotes (e.g., "Hello"). Strings are immutable, meaning once created, their value cannot be changed.

Non-primitive Types (Java) | Java | XQA Learn