Array of Objects in Java

โšก Smart Summary

Array of Objects in Java stores object references in a fixed-size contiguous slot, letting a single variable hold many instances of a class and access each one through an index for iteration, mutation, and passing to methods.

  • ๐Ÿ“ฆ Reference storage: Each slot in a Java array of objects holds a reference to an object, not the object itself, similar to any object variable in Java.
  • ๐Ÿงฑ Two-step creation: Allocate the array with new ClassName[size], then allocate each object with new ClassName() before calling methods on it.
  • โš ๏ธ NullPointerException: Every slot starts as null. Calling a method on an uninitialized slot throws NullPointerException at runtime.
  • ๐Ÿ” Iteration: Use a for loop with array length or an enhanced for loop to walk every object in the array.
  • ๐Ÿ“ Fixed size: An array cannot grow after allocation. Use ArrayList when the number of objects changes at runtime.
  • ๐Ÿ—๏ธ Constructor init: Constructors passed inline during creation give shorter, safer setup than post-hoc setter calls.
  • ๐Ÿšš Method parameter: Passing the array to a method transfers a reference, so changes inside the method are visible to the caller.

Array of Objects in Java

What is an Array of Objects in Java?

A Java array of objects stores multiple object instances of the same class in a single fixed-size container. Unlike a primitive array that stores values such as int, double, or boolean directly in each slot, an array of objects stores references. Every slot points to the memory location of an object, and the object itself lives on the Java heap.

This layout matches how any object variable in Java works. The array simply groups several object references together so you can access them by index. It is the natural choice when the number of objects is known upfront and does not change during the program’s lifetime.

Syntax

ClassName[] obj = new ClassName[array_length];

The right side allocates space for array_length references, all initialised to null. No object of ClassName exists yet, only the container that can hold references to such objects.

How to Create an Array of Objects in Java

Creating a working array of objects always takes two allocation steps. The first allocates the reference container, and the second allocates each object that the container will point to. Skipping the second step is the single most common source of NullPointerException in beginner Java code.

Step 1) Open your code editor and copy the following code:

class ObjectArray {
    public static void main(String args[]) {
        Account obj[] = new Account[2];
        // obj[0] = new Account();
        // obj[1] = new Account();
        obj[0].setData(1, 2);
        obj[1].setData(3, 4);
        System.out.println("For Array Element 0");
        obj[0].showData();
        System.out.println("For Array Element 1");
        obj[1].showData();
    }
}

class Account {
    int a;
    int b;

    public void setData(int c, int d) {
        a = c;
        b = d;
    }

    public void showData() {
        System.out.println("Value of a = " + a);
        System.out.println("Value of b = " + b);
    }
}

Step 2) Save the file as ObjectArray.java, then compile and run it.

Step 3) Note the error. Try to debug it before continuing to Step 4.

Step 4) Inspect the line Account obj[] = new Account[2];. It allocates an array of two reference variables of type Account, but it does not allocate any Account objects. Both slots hold null, and calling obj[0].setData(...) on a null reference throws a NullPointerException at runtime.

Java Array of Objects reference variables

Step 5) Uncomment lines 4 and 5. These two lines create real Account objects and assign them to obj[0] and obj[1]. The array now holds real references, and the code runs cleanly.

Java Array of Objects populated

Output:

For Array Element 0
Value of a = 1
Value of b = 2
For Array Element 1
Value of a = 3
Value of b = 4

How to Initialize an Array of Objects in Java

Beyond the setter-based initialisation shown above, an array of objects can be initialised in three cleaner ways. Each style trades verbosity for clarity, so pick the one that best matches the situation.

  1. Loop initialisation โ€” allocate the array, then walk each index and assign a fresh object. This is the standard pattern for large arrays or when the object count is dynamic.
  2. Constructor initialisation โ€” pass values directly to the constructor at creation time so no separate setter call is needed.
  3. Array literal initialisation โ€” declare and populate in a single statement with an inline { ... } initialiser, ideal for small fixed sets.
class Account {
    int a, b;

    public Account(int a, int b) {   // constructor
        this.a = a;
        this.b = b;
    }
}

public class InitDemo {
    public static void main(String[] args) {

        // 1) Loop initialisation
        Account[] loopArr = new Account[3];
        for (int i = 0; i < loopArr.length; i++) {
            loopArr[i] = new Account(i, i * 10);
        }

        // 2) Constructor initialisation, one slot at a time
        Account[] ctorArr = new Account[2];
        ctorArr[0] = new Account(1, 2);
        ctorArr[1] = new Account(3, 4);

        // 3) Array literal initialisation
        Account[] litArr = {
            new Account(5, 6),
            new Account(7, 8),
            new Account(9, 10)
        };

        System.out.println("loop size   = " + loopArr.length);
        System.out.println("ctor size   = " + ctorArr.length);
        System.out.println("literal size= " + litArr.length);
    }
}

Loop initialisation is the safest default because it guarantees no slot is left null. Constructor initialisation makes intent explicit when each object needs different arguments, and array literals keep small demo code compact. Do not mix styles inside the same array unless you have a reason: consistency makes bugs easier to spot.

Iterating and Accessing Elements in a Java Array of Objects

Once an array of objects is populated, three patterns cover almost every access need. Choose the loop style that matches how much control the code needs over the index.

Classic for loop gives access to the index, which is useful for replacing elements, comparing neighbours, or iterating a subrange.

for (int i = 0; i < obj.length; i++) {
    System.out.println("Element " + i);
    obj[i].showData();
}

Enhanced for loop (the “for-each” loop) hides the index and reads more naturally when the index is not needed:

for (Account acc : obj) {
    acc.showData();
}

Streams (Java 8 and later) convert the array into a pipeline, which is handy for filtering, mapping, or aggregating without writing a loop:

import java.util.Arrays;

Arrays.stream(obj)
      .filter(acc -> acc.a > 0)
      .forEach(Account::showData);

To read or update a single element, use direct index access, for example obj[1].setData(10, 20). Always check the length first with obj.length to avoid ArrayIndexOutOfBoundsException. When any slot could be null, guard the access with a null check or an Optional to keep the program running instead of crashing.

Array of Objects vs ArrayList of Objects in Java

A plain array of objects is fast and predictable, but its fixed size becomes a limitation as soon as the object count changes at runtime. Java’s Collections framework provides ArrayList as the dynamic alternative. The table below highlights when each choice is appropriate.

FeatureArray of ObjectsArrayList of Objects
SizeFixed at creationGrows and shrinks automatically
DeclarationAccount[] a = new Account[5];List<Account> list = new ArrayList<>();
Access elementa[i]list.get(i)
Add elementNot supported after creationlist.add(obj)
Type safetyCompile-time typed by declarationGenerics enforced at compile time
PerformanceMarginally faster indexed readsAmortised O(1) add, some overhead per element
Preferred whenSize is known and fixedSize is unknown or changes at runtime

Use an array when a tight memory footprint and predictable indexing matter, for example in matrix layouts or performance-critical hot paths. Reach for ArrayList in most everyday application code, because the ability to add and remove without reallocation outweighs the small per-element overhead.

FAQs

An array of objects in Java is a fixed-size container that stores references to instances of the same class. Each slot points to an object on the heap, and elements are accessed by zero-based index using square brackets.

Declare the array with ClassName[] arr = new ClassName[size], then create each object with new ClassName() in a loop or with an inline array literal. Both steps are required; the first allocates only reference slots.

Because new ClassName[size] only allocates the array itself. Every slot starts as null, so calling any method on that slot throws NullPointerException. Fix it by assigning a new ClassName() to each index before use.

An array has a fixed size chosen at creation, while ArrayList grows and shrinks automatically. Arrays give slightly faster indexed reads; ArrayList adds convenient add, remove, and stream methods for everyday application code.

Use a classic for loop with arr.length when you need the index, or an enhanced for-each loop for simple iteration. For filtering or transformation, wrap the array with Arrays.stream(arr) and chain the pipeline you need.

Declare the parameter as ClassName[] name, then call the method with the array variable. Java passes the array reference by value, so mutations to element fields inside the method are visible to the caller.

Machine learning code generators recognise the two-step allocation pattern and complete the missing new ClassName() lines that beginners forget. They also suggest ArrayList when the target collection size is unknown, reducing NullPointerException bugs.

Yes. GitHub Copilot generates array declarations, constructor loops, iteration blocks, and ArrayList conversions from a comment describing the domain model. Review generated code for correct constructor arguments and safe null handling before use.

Summarize this post with: