Skip to main content

4.4 Arrays in Depth

Overview

Arrays in Java are a fundamental data structure that allows you to store multiple values of the same type in a contiguous memory location. While basic array usage is straightforward, understanding how arrays interact with other advanced topics like collections, subtyping, and generics is crucial for mastering Java.

Working with Variable Arguments

In Java, variable arguments (varargs) allow a method to accept zero or more arguments of a specified type. Behind the scenes, varargs are implemented using arrays.

public void printNumbers(int... numbers) {
for (int number : numbers) {
System.out.println(number);
}
}

You can call the method with any number of arguments:

printNumbers(1, 2, 3);  // Passes an array with 3 elements

Converting between Arrays and Collections

Java provides utilities to convert between arrays and collections. The Arrays.asList() method converts an array to a List:

String[] array = {"one", "two", "three"};
List<String> list = Arrays.asList(array);

To convert a List back to an array:

List<String> list = Arrays.asList("one", "two", "three");
String[] array = list.toArray(new String[0]);

Understanding Arrays and Subtyping

In Java, arrays are covariant, which means you can assign an array of a subtype to an array of a supertype. For example:

Integer[] intArray = {1, 2, 3};
Number[] numArray = intArray; // Valid because Integer is a subtype of Number

However, covariance comes with a risk. If you try to insert an element that is not compatible with the original array, you will get an ArrayStoreException at runtime:

numArray[0] = 3.14;  // Throws ArrayStoreException

Understanding Covariance of Arrays

Arrays in Java are covariant, meaning that an array of a subclass type can be assigned to an array of a superclass type. This is not the case with generics, which are invariant.

Integer[] intArray = {1, 2, 3};
Number[] numArray = intArray; // Valid because Integer is a subtype of Number

However, this can lead to runtime exceptions if you try to store incompatible types:

numArray[0] = 1.5;  // Throws ArrayStoreException

Exploring Arrays and Generics

While arrays are covariant, generics in Java are invariant. This means you cannot assign a generic type of one subtype to another, even if their base types are compatible.

List<Integer> intList = new ArrayList<>();
List<Number> numList = intList; // Compile-time error: incompatible types

This difference between arrays and generics is important when working with complex data structures and designing APIs.

Summary

Understanding arrays in depth involves recognizing their role in advanced topics such as collections, subtyping, covariance, and generics. Arrays are flexible but have certain limitations, especially when compared to Java’s generic system. Mastering these concepts is key to writing robust, type-safe code in Java.