Monday, June 16, 2014

Java Generics: The Difference between Java Arrays and Generic Lists | OneWebSQL



Let's begin with a puzzle. Suppose we have a class Student which inherits from a class Person:
?
1
2
3
public class Person { ... }
 
public class Students extends Person { ... }
We have the following variables:
?
1
2
3
4
List<Person> personList;
List<Student> studentList;
Person[] personArray;
Student[] studentArray;
Which of the following assignments is correct?
?
1
2
3
4
studentList = personList;
personList = studentList;
studentArray = personArray;
personArray = studentArray;

Solutions

?
1
studentList = personList;
Answer: incorrect.
This one is obvious to anyone. Surely a list of Persons cannot be assigned to a variable containing a list of Students because the list can contain Person objects which are not Students.
?
1
personList = studentList;
Answer: incorrect.
This assignment is not correct because List<Student> is not a subclass of List<Person>. This is surprising to many Java beginners. Here's an explanation. 
Imagine for a moment that the assignment was correct. Then the variable personList would hold a reference to the studentList object (a list of Students). But the variable personList only knows that it is a list of Persons. One can try to insert a Professor into the list.
?
1
personList.add(new Professor("A","B")); //incorrect but compiles
The compiler does not know that the insert operation is incorrect. The runtime system has no way of knowing that the insert is incorrect. Recall from my previous post that at runtime the type of studentList object is List. All objects, including Professor, can be put into something of type List.
If List<Student> were a subclass of List<Person>, then the generics would not ensure type safety as it is supposed to guarantee.
?
1
studentArray = personArray;
Answer: incorrect.
This assignment is not correct, for the same reasons as the similar assignment with lists is not correct.
?
1
personArray = studentArray;
Answer: correct.
Here we have another surprise. Arrays in Java are covariant, which, in our example, means that if Student is a subclass of Person (which it is), then Student[] is a subclass of Person[].
Arrays are covariant
Why is the covariance allowed for arrays and forbidden for parametrized lists? Are the two that much different? 
Java arrays know the type of its elements and they check at runtime whether an element can be inserted into it.
?
1
personArray[0] = new Professor("A","B"); //runtime exception
If we try to insert a Professor into an array of Students (even if it's referenced via a Person[] variable) an ArrayStoreException will be thrown.
Again, it's not possible that an exception is thrown in a similar situation with parametrized lists. The generic lists do not know the type of its elements at runtime. They cannot checkwhether an element can be inserted into the list. As a consequence, List<Person> is not a subclass of List<Student>.
Lists are not covariant
It is possible to have a variable which can hold both a list of Persons and a list of Students but you have to use a new construction, wildcards. But that's a topic for a different post.
Java arrays know the type of its elements and they check at runtime whether an element can be inserted into it.
it's not possible that an exception is thrown in a similar situation with parametrized lists. The generic lists do not know the type of its elements at runtime. They cannot checkwhether an element can be inserted into the list. As a consequence, List<Person> is not a subclass of List<Student>.
Read full article from Java Generics: The Difference between Java Arrays and Generic Lists | OneWebSQL

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts