0
ArrayList<String> list = new ArrayList<String>();
list = (ArrayList<String>) Files.readAllLines(FilePath);

In the above code, if I remove the explicit casting in second line, the compiler gives an error. Why is this explicit cast required considering the fact that Files.readAllLines(FilePath) returns a List<String>, and ArrayList<String> implements List<String> ?

5
  • 1
    Use List<String> list instead. Commented Jul 29, 2019 at 11:48
  • 6
    Files.readAllLines(FilePath) returns a List<String>, but the implementation of the list might not be ArrayList. Your cast is therefore unsafe. You should just do List<String> list = Files.readAllLines(filePath);. Commented Jul 29, 2019 at 11:49
  • 1
    Also note, your cast should be in parentheses, like: list = (ArrayList<String>) Files.readAllLines(FilePath); Commented Jul 29, 2019 at 11:50
  • 1
    Every ArrayList is a List, but not every List is an ArrayList. Commented Jul 29, 2019 at 11:51
  • 1
    @cameron1024 Thanks for pointing out. I missed those while typing the code here though my original code was with parenthesis. Edited. Commented Jul 29, 2019 at 11:52

3 Answers 3

4

The method Files.readAllLines() only guarantees to return an object of type List<String>, but not of the more specific type ArrayList<String>. The actual implementation type of the returned list may vary between different JDK implementations (they just need to be sub-classes of List<String>, so while a cast to ArrayList<String> may work in your environment with your JDK implementation it may not work in another.

If you really need your list to be an ArrayList, you can use this code instead:

ArrayList<String> list = new ArrayList<String>();
list.addAll(Files.readAllLines(FilePath));
Sign up to request clarification or add additional context in comments.

Comments

4

As you've said, any ArrayList<T> is a List<T>. But the opposite is not true: a List<T> is not always an ArrayList<T>.

This means that if the method readAllLines is returning a List<T>, then you can assign the value to a List<T> variable, not any of its subtypes without an explicit downcast (which should always be avoided).

I don't even see why you would want to downcast it to ArrayList<T>, the less you imply about a type, freer you are.

Comments

1

In your example, you are doing a downcasting, i.e. you want to cast a parent class to a child class. This is very unsafe, since a child may offer more than a parent. In your example, an ArrayList has additional functionalities. Thus, to ensure safety, the compiler will never allow an implicit downcasting (but upcasting is ok, as a child has necessarily all the functionalities of a parent).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.