Glains
Glains

Reputation: 2863

Cast interface with generic type parameter extending Comparable

I have got a very simple interface with a generic type parameter.

public interface Foo<T> {
    void add(T element);
}

Now, i have a variable of this interface in a class like this:

public class Bar {

    private Foo<?> foo;

    public void action() {
        Object o = new Object();
        (Foo<Object> foo).add(o); // in my case i know that this will work
    }
}

But now, if i modify the interface so that the type parameter must extend Comparable<T>, how can i achieve the same effect as above?

public interface Foo<T extends Comparable<T>> {
    void add(T element);
}

public class Bar {

    private Foo<?> foo;

    public void action() {
        Object o = new Object();
        // compiler error, since Object does not extent Comparable
        (Foo<Object> foo).add(o);
    }
}

Update:

I have a lot of classes implementing this interface, for example:

public class IntFoo implements Foo<Integer> {

    public void add(Integer element) {
        // do something
    }
}

In my Bar class i have a Foo<?> and i want to add elements to it using add(). I have taken precautions (for example with instanceof) to only add an Integer if it is of type Foo<Integer>.

Upvotes: 0

Views: 1033

Answers (1)

Makoto
Makoto

Reputation: 106400

To understand why your approach is not working out the way you expect, you have to first understand the wildcard you're using - ?, and a little background on generics vs. casting.

A generic with wildcard is regarded as a "don't-care" or "unknown" type; that is to say, you neither know nor care what type is in that generic, since due to type erasure, you can't retrieve it later on.

Generics were introduced to spare us the hassle or need to cast to a specific type that we wanted. We could define a homogeneous type and simply deal with that as opposed to having to cast every time. Generics allow us to deal with mismatched typings as a result of a bad cast at compile time, meaning that the code won't even compile if Java believes it to be a bad type cast.

Since casts are the only way for a developer to usurp control from the compiler, if you cast, you're telling the compiler that you know what you're doing. If you don't, you'll get a runtime exception.


All of that to say...

The only way you're going to get any element of type Comparable into Bar is if you have a typed and bound generic.

public class Bar<T extends Comparable<T>> implements Foo<T> {

    private Foo<T> foo;

    public void add(T object) {
        foo.add(object);
    }
}

Upvotes: 1

Related Questions