How do you cast a List of supertypes to a List of subtypes?
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
In software development, specifically within object-oriented programming, casting is a common operation wherein a variable of one type is converted into another. While straightforward in most cases, casting a list of supertype elements to a list of subtype elements presents unique challenges and considerations. This type of casting often arises in scenarios involving polymorphism, where a method might return a list of elements of a generic supertype, but specific operations require handling them as a specific subtype.
Understanding the Basics: Supertypes and Subtypes
To begin with, it's crucial to understand the definitions of supertypes and subtypes within the context of a programming language like Java. A subtype is a class that extends another class (the supertype) or implements an interface. For instance, consider a class Animal that has several subclasses such as Cat and Dog.
Approach to Casting Lists
Given a List<Animal>, you might find yourself needing to treat it as a List<Cat> or a List<Dog> to leverage unique methods provided by these subclasses. Directly casting the list, such as (List<Dog>) listAnimals, is unsafe and generally incorrect. This is because Java’s generics are invariant, meaning that even though Cat is a subtype of Animal, a List<Cat> is not a subtype of List<Animal>.
Safe Approaches to Converting Lists
Using a Filtered and Casted Loop
One safe way to achieve the conversion is by iterating over the list, checking each element's type, and then adding the appropriately casted objects to a new list of the subtype.
This method ensures type safety by using instanceof to check the type before casting and adding to the new list. This avoids ClassCastException.
Using Java Streams (Java 8+)
A more modern and concise approach is to use Java Streams:
This method also maintains type safety and leverages the powerful Stream API for concise processing of collections.
Downcasting vs Upcasting
Upcasting refers to casting from a subtype to a supertype, which is always safe and can be done implicitly. Downcasting, however, involves casting from a supertype to a subtype. Downcasting can be dangerous and should be handled with care, generally requiring explicit checks as shown above.
Summary Table
Below is a summary of key points discussed:
| Method | Description | Safety |
| Direct Cast | (List<Dog>) listAnimals | Unsafe and likely to cause ClassCastException |
| Filtered Loop | Using a loop with type checks and explicit casting | Safe, but verbose |
| Streams API | Leveraging Java's Stream API with methods like filter and map | Concise and safe |
Potential Pitfalls and Best Practices
Directly casting without checking types can lead to runtime exceptions, notably ClassCastException. It is best practice to ensure type safety either through explicit checks (using instanceof) or by utilizing Java's generic type system, particularly bounded wildcards that can promise compiler-level type safety to some extent.
Conclusion
Casting a list of supertypes to a list of subtypes, while not directly supported by Java’s type system, can be achieved safely through careful implementation of type checks and controlled list population. Understanding the limitations and risks inherent in unchecked casting is crucial to avoid common pitfalls in type management within Java and similar statically typed languages.
Related reading
- How do you convert a byte array to a hexadecimal string, and vice versa?
- How do you convert a string to a byte array in .NET?
- How do you create a dictionary in Java?
- How do you create nested dict in Python?
- How do you compare two version Strings in Java?
- How do you configure Embedded MongDB for integration testing in a Spring Boot application?
- How do you determine if two HashSets are equal by value, not by reference?
- How do you divide each element in a list by an int?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseData Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.