Question
Why can't we assign ArrayList<Child> to List<Parent> in Java?
List<Parent> myList = new ArrayList<Child>();
Answer
The inability to assign an `ArrayList<Child>` to a `List<Parent>` in Java is a consequence of the way Java implements generics and type safety. Java generics are invariant, meaning that even if `Child` is a subclass of `Parent`, `ArrayList<Child>` is not a subclass of `ArrayList<Parent>`.
List<? extends Parent> myList = new ArrayList<Child>();
// This works because it allows myList to be a list of any type that extends Parent.
Causes
- Java generics are invariant, meaning `List<Child>` and `List<Parent>` are treated as completely separate types.
- Allowing `List<Child>` to be assigned to `List<Parent>` would violate type safety, potentially leading to runtime errors.
- In a type-safe environment, invoking methods expecting `Parent` objects on `Child` objects could lead to unexpected behavior.
Solutions
- Use wildcard types to allow flexibility: `List<? extends Parent>` could be used in certain contexts, although it has its own limitations.
- Consider using raw types (not recommended due to type safety concerns) or redesigning your class structures to better reflect type hierarchies.
- Utilize generics in a way that ensures type compatibility, such as creating a common interface or abstract class.
Common Mistakes
Mistake: Assuming that List<Child> can substitute for List<Parent> due to inheritance.
Solution: Remember that Java generics are invariant. Always specify the correct types.
Mistake: Using raw types to work around the type compatibility issue.
Solution: Avoid using raw types; they bypass the safety features provided by Java generics.
Helpers
- Java generics
- invariant generics
- List<Parent>
- ArrayList<Child>
- Java type safety