File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Generics: subtype convariance issues Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Generics: subtype convariance issues" Watch "Generics: subtype convariance issues" New topic
Author

Generics: subtype convariance issues

Kim Ming Yap
Ranch Hand

Joined: Dec 17, 2008
Posts: 53

As we know in Java, subtype covariance does not exists since generics are done through type erasure in Java.

Example:
Set <Number> s1 = new HashSet <Number>(); ok
Set <Number> s1 = new HashSet <Integer>(); not ok

Why this work then.

=====================



[Ankit: added code tags]
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

Kim, you are confused because of using U with both class ClassA and ClassE. The types of class A and E are different from each other. So you can write this too

Basically ClassE and ClassA's type are different from each other. ClassE extends ClassA<Number>, so the compiler knows that for polymorphic assignment between ClassE and ClassA, the type of the reference variable of ClassA should be Number, it cannot be Integer


SCJP 6 | SCWCD 5 | Javaranch SCJP FAQ | SCWCD Links
Kim Ming Yap
Ranch Hand

Joined: Dec 17, 2008
Posts: 53

Thanks for your responds.
I understand what you are saying ..

I have always thought the <U> in class E is different from class A all the while.
I do understand that class<Number> is the superclass of classE<U> and hence on polymorphic assignment like below it works:

ClassA<Number> c1 = new ClassE<Integer>();

what i dont understand is:
1. For concrete parameterized type

Set <Number> s1 = new HashSet<Integer>();
Java does not allow this since the type has been erased. // there's were wild card comes in handy

so why does java allows a concrete parameterized type:

ClassA<Number> c1 = new ClassE<Integer>();

works?

If you look at these 2 statements:

Set <Number> s1 = new HashSet<Integer>(); // not allowed
ClassA<Number> c1 = new ClassE<Integer>(); //allowed

They are no different. Both has subtype with concrete parameterized type being assignment to supertype of concrete parameterized type.
That's what confuses me.
Please advice.
Thanks.
Ireneusz Kordal
Ranch Hand

Joined: Jun 21, 2008
Posts: 423
Kim Ming Yap wrote:

Set <Number> s1 = new HashSet<Integer>(); // not allowed
ClassA<Number> c1 = new ClassE<Integer>(); //allowed


Set is an interface, not a class.
Look at definition of HashSet:
class HashSet<U> implements Set<U> ...

So, if you change ClassA with InterfaceA in your example:


then this is not allowed:




Simillary in this code:


the following is not allowed:



Kim Ming Yap
Ranch Hand

Joined: Dec 17, 2008
Posts: 53

N/A
Kim Ming Yap
Ranch Hand

Joined: Dec 17, 2008
Posts: 53

Thanks for your reply. I understand what you are saying ..
I have a better one as shown below:
=============================

public class Generics {

public static void main(String [] args) {

ClassA <Number> c1 = new ClassA<Number>();
ClassA <Integer> c2 = new ClassA<Integer>();
c1 = c2; // (A) Does not work
ClassA <Number> c4 = new ClassF<Integer>(); // (B) Does not work
ClassA <Number> c3 = new ClassE<Integer>(); // (C) work

}

}

class ClassA<U> implements Comparable<U>{
public int compareTo(U a) {return 0;}
}

class ClassE<U> extends ClassA<Number>{}

class ClassF<U> extends ClassA<U>{}

==================================

I guess the root question is what's the difference between these 2:

class ClassE<U> extends ClassA<Number>{}
class ClassF<U> extends ClassA<U>{}

I understand the both:
Former means ClassA<Number> is the superclass of ClassE<U> where <U> is any unbounded type
Latter means instantation of ClassF say ClassF<Number> is always a subtype of ClassA<Number>

Honestly i just dont see any difference between these 2.
Confusing ..
Ankit Garg
Sheriff

Joined: Aug 03, 2008
Posts: 9321
    
  17

Kim Ming Yap wrote:I guess the root question is what's the difference between these 2:

class ClassE<U> extends ClassA<Number>{}
class ClassF<U> extends ClassE<U>{}

In the first one, you are specifying that the type of ClassE can be anything but its super class is ClassA<Number>. In the second case we are saying that whatever the type of ClassF is, will be the type of ClassE. If we add a few elements to ClassA and ClassE, we can notice the difference


 
wood burning stoves
 
subject: Generics: subtype convariance issues