Why an ArrayList cannot contain primitives in Java

Why an ArrayList in Java cannot contain primitives like int, double or char

In Java, an ArrayList is a very convenient object that allows us to create and manage variable-length arrays. However, in Java, an ArrayList also has a weird quirk. You cannot declare an ArrayList that uses Java primitives. Below are a few examples:

import java.util.ArrayList;

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<int> intList = new ArrayList<int>();
		ArrayList<double> doubleList = new ArrayList<double>();
		ArrayList<char> charList = new ArrayList<char>();
	}
}

What’s the solution?

To create an ArrayList with primitives, you will need to use classes that box these primitives inside an object. Hence, for the above example:

import java.util.ArrayList;

public class ArrayListTest {
	public static void main(String[] args) {
		ArrayList<Integer> intList = new ArrayList<Integer>();
		ArrayList<Double> doubleList = new ArrayList<Double>();
		ArrayList<Character> charList = new ArrayList<Character>();
	}
}

Even though these boxed primitives are objects, you can use them as though they are primitives, as Java does automatic boxing and unboxing of these primitives. For example:

import java.util.ArrayList;

public class BoxedPrimitivesTest {
	public static void main(String[] args) {
		Integer a = 10; // You can treat this as though it is a primitive.
		int b = 25;
		System.out.println(a + b);
	}
}

Article continues after the advertisement:


Below is a list of all 8 primitives in Java, as well as their boxed variants:

Primitive TypeBoxed ClassArrayList initialiser
byteByteArrayList<Byte>
shortShortArrayList<Short>
intIntegerArrayList<Integer>
longLongArrayList<Long>
floatFloatArrayList<Float>
doubleDoubleArrayList<Double>
charCharacterArrayList<Character>
booleanBooleanArrayList<Boolean>

As you can see, most of the boxed types use the same word as the primitive, with the first letter capitalised. The only exceptions to these are the int and char types, which are properly spelt out as Integer and Character respectively.

Why does this happen?

If you’ve tried out other languages similar to Java, you may find that not all of them have this quirk. C#, for example, allows their variant of the ArrayList to use primitives:

using System.Collections;
class TestClass {
	static void Main(string[] args) {
		List<int> intList = new List<int>();
	}
}

This is because C# allows the use of primitive types in their generic functions, whereas Java does not, and the constructor for an ArrayList is a generic function. According to ChatGPT:

In Java, ArrayLists cannot directly hold primitive types because the Java Generics system only supports reference types as type parameters.

The Java Generics system was designed to provide compile-time type safety and facilitate code reuse by working with reference types. To work around this limitation, Java introduced auto-boxing and auto-unboxing. Auto-boxing allows automatic conversion between primitive types and their corresponding wrapper classes (e.g., int to Integer), while auto-unboxing performs the reverse operation.

To be frank, I don’t know what all of that means, but as long as you know how to use boxed primitives in Java, you should be fine.

Feel free to sound out in the comments below if you have anything to add.


Article continues after the advertisement:


Leave a Reply

Your email address will not be published. Required fields are marked *

Note: You can use Markdown to format your comments.

For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

I agree to these terms.

This site uses Akismet to reduce spam. Learn how your comment data is processed.