1

Why doesnt the following code get compiled? I know changing it to String works but why we are unable to typecast from string to object?

List<Object> c4 = new ArrayList<String>(); 
0

5 Answers 5

6

When using generics, the inheritance concept is little bit different. You need to use wildcards and sub typing to achieve inheritance with generics.

As per oracle tutorial

Note: Given two concrete types A and B (for example, Number and Integer), MyClass<A> has no relationship to MyClass<B>, regardless of whether or not A and B are related. The common parent of MyClass<A> and MyClass<B> is Object.

Sign up to request clarification or add additional context in comments.

4 Comments

That link is so helpful
List<? extends Object> c4 = new ArrayList<String>() may cause errors at runtime?
No it will not. Again as I said in my comment you cannot add anything to the List in this case.
Generics are compile time type safety stuff. After compilation generics will be replaced with corresponding nearest objects (type erasure) docs.oracle.com/javase/tutorial/java/generics/erasure.html.
1

Although String is a subclass of Object, List<String> is not a subclass of List<Object>.

The reason is that if it were a subclass, it would allow the following:

List<String> listA = new ArrayList<String>(); List<Object> listB = listA; // normally a compile error listB.add(new Integer(1)); // it would allow this String s = listA.get(0); // boom! ClassCastException 

Comments

1

Assuming this worked

List<Object> c4 = new ArrayList<String>(); 

you could then go add

c4.add(new YourCrazyObjectThatIsNotAString()); 

which doesn't make sense because c4 should really be an ArrayList of Strings.

Generics were invented in part so that this wouldn't happen. Bohemian and Nambari have the technical reason.

Comments

1
List<Object> c4 = new ArrayList<String>(); 

Now you can add anything that is Object which is technically every Object. Which is incorrect because List is really of String. Hence it is not allowed.

So lets say you add some custom Object to the list. Then while fetching the object it will try to typecast to String which will throw incorrect cast exception. To avoid this ambiguity java does not allow it.

In general

List<SomeObject> l = new ArrayList<SubClassOfSomeObjectClass>; 

is not allowed. However you can do something like

List<? extends SomeObject> l = new ArrayList<SubClassOfSomeObject>; 

2 Comments

In this case List<? extends Object> c4 = new ArrayList<String>(); also there is a possibility of exception right ?
Nope! This will compile and run just fine. Only drawback of this is you cannot add anything to the List(except null of-course).
0

Consider following code:

List<String> ls = new ArrayList<String>(); List<Object> lo = ls; lo.add(new Integer(5)); String x = ls.get(0); 

Generics are invented to prevent some of class-cast exceptions. But if it was possible to assign List<String> to an List<Object> then you could do everything to break their power.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.