2

Let's consider block of code:

List<List<Object>> list = new ArrayList();
list.add(new ArrayList<Object>); //Line 2
list.add(new LinkedList<Object>); //Line 3
list.add(new LinkedList<Date>); //Line 4

Ok:

  1. As far as I know polimorphic assigment DO NOT work within Generics

    Question: But in the line: 2, 3, 4 Is there List, ArrayList, LinkedList are not generic for collection with name list??

  2. Line 4 won't compile, regardless of Date is subtype of Object

    Question: Back to the question 1, Is this means that Object and Date is case of polymorphism and generics???

Can understand it. Please help.


And one more question:

List list = new ArrayList<String>();
  list.add(new Integer(1));
  System.out.print(list.get(0));

Output: 1

Will compile, means no type safety. Why? Even if List list- raw type, and ArrayList<String> parametrized type, any way is useless. Why?

Community
  • 1
  • 1
java_user
  • 929
  • 4
  • 16
  • 39
  • `list.add(new List);` How did you manage to instantiate an interface? Is this your own class and not the Java interface `List`? – Chetan Kinger May 24 '15 at 16:35
  • take a look at my answer and let me know if you need any clarifications. – Chetan Kinger May 24 '15 at 17:11
  • Also see [*Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?*](http://stackoverflow.com/q/2745265/2891664) and [*What is a raw type and why shouldn't we use it?*](http://stackoverflow.com/q/2770321/2891664). – Radiodef May 24 '15 at 17:25
  • Invariance of generics only applies to the generic part. Classes and interfaces work the normal way. An `ArrayList` is a `List`. – Radiodef May 24 '15 at 17:27
  • STILL DID NOT GET AN ANSWER WHAT I ASKED: I have List> so why List which is generic for List can be polimorphicaly subclassed I mean -> it turns out that List - Can be substituted with subclass - can not A thought that List this is generic for List and can not be changed. How this is happened???? – java_user May 24 '15 at 17:52
  • And SECOND question: why copmpiler allow you to write List list = new ArrayList(); Particulary ArrayList() even it is usless and I can put anything I want to ArrayList of Strings??? – java_user May 24 '15 at 17:56
  • In the second question, it is the List declaration that defines the type, not the type of the object assigned. For why, you need to look up type-erasure. That is another question. I suggest you read up about it before going further. – rghome May 24 '15 at 18:12

3 Answers3

1

FIRST QUESTION:

So the rule is that: a subclass can do everything that the superclass can do (and maybe more).

A<X> is a subclass of B<X> if A is a subclass of B

This is because A can do anything that B can do. Wherever you can use B<X> you can use A<X>.

For example:

List<Object> lo
ArrayList<Object> alo

ArrayList<Object> alo can do everything List<Object> lo can do so it is a subclass.

But:

A<X> is not a subclass of A<Y>, even if X is a subclass of Y

This is because A<X> cannot do everything that A<Y> can do.

In the case of:

List<Object> lo
List<Date> ld

List<Object> lo can add any object to lo, but List<Date> ld can only add dates, so it can't be a subclass.

SECOND QUESTION:

List list = new ArrayList<String>();
list.add(new Integer(1));

Yes - this is very bad and doesn't work. That is why you get a warning.

The List declaration is the significant part here in determining the type of list and what you can do with it. At runtime, the ArrayList<String> just looks like an ArrayList due to something called type-erasure, so that will not prevent bad things being added either.

List is a raw type. References to generic type List should be
parameterized

CAVEAT:

The statement a subclass can do everything that the superclass can do is a general statement of design intent and not intended to be literally true. You can, of course, find counter examples.

rghome
  • 8,529
  • 8
  • 43
  • 62
  • `a subclass can do everything that the superclass can do`. Not true. Consider a class `A` that has a method that does not have any access specifier (e.g void methodA()). A subclass in the same package as `A` can do whatever `A` can do. A subclass in a different package than `A` cannot do whatever `A` can do because it will not inherit `methodA()` – Chetan Kinger May 24 '15 at 17:02
  • Good point - I hadn't thought of it, but kind of a fringe case due to Java strangeness. I think it would confuse things to add it to the answer. – rghome May 24 '15 at 17:05
  • But it's the main premise on which your answer is based. A premise that is incorrect makes the argument/conclusion incorrect. :) – Chetan Kinger May 24 '15 at 17:07
  • 1
    No it doesn't if the counter example is not within the scope of the discussion. My argument is a general one about design principles and not about specific implementation details. Going into details would obscure the point. But, your case is interesting anyway. – rghome May 24 '15 at 17:11
  • You are broadening the scope to justify your answer. The question has been tagged as `java` and my counter example is very much within the scope :) – Chetan Kinger May 24 '15 at 17:37
  • STILL DID NOT GET AN ANSWER WHAT I ASKED: I have List> so why List which is generic for List can be polimorphicaly subclassed I mean -> it turns out that List - Can be substituted with subclass - can not A thought that List this is generic for List and can not be changed. How this is happened???? – java_user May 24 '15 at 17:57
  • And SECOND question: why copmpiler allow you to write List list = new ArrayList(); Particulary ArrayList() even it is usless and I can put anything I want to ArrayList of Strings??? – java_user May 24 '15 at 17:57
  • list can add List so it can also add ArrayList as ArrayList is a subclass of List, therefore ArrayList is a subclass of List. – rghome May 24 '15 at 18:02
  • Second question - the compiler allows you to do this for several reasons. One important one is that it lets you interact with old pre-generics code. The compiler warns you that it is not safe. – rghome May 24 '15 at 18:03
  • I know that! But I declare parametrized type for list!!! So that mean that I can substitute parametrized type T with subclass and generic type E I can not substitute with subclass some how. Or what???How compiler identify that rules to apply – java_user May 24 '15 at 18:04
  • True. I know that too from question two. but!!!!! Why the compiler allow me to declare parametrized type, to confuse my expectations??? )) – java_user May 24 '15 at 18:06
  • For question 1, it is not clear what you mean. I suggest edit your question with a specific example. For question two, I think it is already answered. You can mix generics and non-generics code for reasons of compatibility. The compiler doesn't know on the next line you are going to add a bug. At run-time, due to **type-erasure** the parameterised list won't check what you add to it. – rghome May 24 '15 at 18:10
  • @rghome `At run-time, due to type-erasure`. Not true again. Type erasure happens at compile time itself. – Chetan Kinger May 25 '15 at 06:57
  • At run-time ... due to type erasure (which happened at compile time) ... – rghome May 25 '15 at 07:24
0

As far as I know polimorphic assigment DO NOT work within Generics

That's wrong. A reference of type ArrayList<E> and a reference of type LinkedList<E> are both subtypes of a reference of type List<E>.

Line 4 won't compile, regardless of Date is subtype of Object

A reference of type LinkedList<T> is not a subtype of a reference of type List<E> (Even if T is a subtype of E)

Even if List list- raw type, and ArrayList parametrized type

You declare a reference of type List. This is conceptually the same as declaring a reference type of List<Object>. Calls to any method (weather static or instance method) are resolved at compile time using the reference type. Since the reference type is List (i.e a raw list), the compiler will allow you to add an object of any type to the list. When the class is compiled, the statement ArrayList<String> is converted to ArrayList by the compiler. This is known as type-erasure. This also the reason why you don't face any issues at runtime.

Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
  • STILL DID NOT GET AN ANSWER WHAT I ASKED: I have List> so why List which is generic for List can be polimorphicaly subclassed I mean -> it turns out that List - Can be substituted with subclass - can not A thought that List this is generic for List and can not be changed. How this is happened???? – java_user May 24 '15 at 17:57
  • And SECOND question: why copmpiler allow you to write List list = new ArrayList(); Particulary ArrayList() even it is usless and I can put anything I want to ArrayList of Strings??? – java_user May 24 '15 at 17:57
0

As far as I know polimorphic assigment DO NOT work within Generics

Actually you are talking about Generics and Inheritence.

so if you have List<Animal> i.e list of animal you can add any animal under list like cat,dog but you can cant assign list of dog to list of animal

Here is the example

psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog());
method1(list1);// compilation error
}

public static void method1(List<Animal> list1) {
list1.add(cat); // Good
list1.add(dog); // Good
}

So you did not get any error on line 2/3 but line 4 will give compilation error because new LinkedList<Date> is not child of List<Object>

UPDATE:- if you want to assign list of dog to list of animal then see below

psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog());
method1(list1);// good
}

public static void method1(List<? extends Animal> list1) {
list1.add(cat); // compilation error
list1.add(dog); // compilation error
}
M Sach
  • 33,416
  • 76
  • 221
  • 314
  • STILL DID NOT GET AN ANSWER WHAT I ASKED: I have List> so why List which is generic for List can be polimorphicaly subclassed I mean -> it turns out that List - Can be substituted with subclass - can not A thought that List this is generic for List and can not be changed. How this is happened???? – java_user May 24 '15 at 17:56
  • And SECOND question: why copmpiler allow you to write List list = new ArrayList(); Particulary ArrayList() even it is usless and I can put anything I want to ArrayList of Strings??? – java_user May 24 '15 at 17:57