Generic java class that stores comparables
Asked Answered
P

3

5

I have a generic java class that stores comparables:

public class MyGenericStorage<T extends Comparable<T>> {
    private T value;

    public MyGenericStorage(T value) {
        this.value = value;
    }

    //... methods that use T.compareTo()
}

I also have an abstract class called Person:

public abstract class Person implements Comparable<Person>

and two concrete subclasses, Professor and Student:

public class Professor extends Person
public class Student extends Person

now when I want to create a MyGenericStorage like so, I get an error:

//error: type argument Student is not within bounds of type-variable T
MyGenericStorage<Student> studStore = new MyGenericStorage<Student>(new Student());

//this works: 
MyGenericStorage<Person> persStore = new MyGenericStorage<Person>(new Student());

I think this is because I have a fundamental problem with understanding generics. Can someone explain this to me, and also, how to fix it?

EDIT:

I have changed MyGenericStorage to the following:

public class MyGenericStorage<T extends Comparable<? super T>> 

and now it seems to work. Can someone explain why?

Pulpboard answered 29/11, 2011 at 17:53 Comment(1)
What if you change it to public class Student extends Person implements Comparable<Student>?Returnee
S
6

You can fix this with the following declaration for MyGenericStorage:

class MyGenericStorage<T extends Comparable<? super T>> { …

This means that T must have a Comparable implementation that accepts some supertype of T. In the case of Student and Professor, the supertype represented by the bound (?) is Person.


Update: "now it seems to work. Can someone explain why?"

Well, I tried in my original answer, but let me give it another shot.

? super T means "some supertype of T". Suppose T in this case is Student. So, Student must implement Comparable "for some supertype of Student"

Student extends Person, which implements Comparable<Person>. So, Student does indeed implement Comparable "for some supertype of Student".

If you have questions about Java Generics, the best place to start is Angelika Langer's FAQ. In this case, the entry about bounded wild-cards may be helpful.

Slenderize answered 29/11, 2011 at 18:13 Comment(1)
Thank you very much for the explanation, I didn't see your answer at the time I edited the question :-)Pulpboard
U
5

Your problem is that Person extends Comparable<Person>, so it's ok, but Student extends Person and thus it extends Comparable<Person> not Comparable<Student>.

In your constraint you are saying <T extends Comparable<T>>, thus they must be the exact same type. Derived types are not acceptable.

Unwrap answered 29/11, 2011 at 17:57 Comment(0)
M
1
public class MyGenericStorage<T extends Comparable<T>>

The above requires you to have the type given to the generic class to extend a class which is omparable with itself. In short, you're saying that Person must implement Comparable<Student> and Comparable<Professor>. That's why it can't be used.

Manzoni answered 29/11, 2011 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.