Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with casting a nested generic Set

Tags:

java

generics

I stumbled upon this interesting cast/generics problem today:

public class A {

    Map<Class<? extends B>, List<Set<B>>> mapListSet = new HashMap<>();
    Map<Class<? extends B>, Set<B>> mapSet = new HashMap<>();

    public <T extends B> List<Set<T>> foo(Class<T> clazz) {
        List<Set<T>> listSet = (List<Set<T>>) mapListSet.get(clazz);

        return listSet;
    }

    public <T extends B> Set<T> bar(Class<T> clazz) {
        Set<T> set = (Set<T>) mapSet.get(clazz);

        return set;
    }
}

class B {

}

I can compile the method "bar" with only one warning from the IDE, whereas the IDE completely refuses to compile method "foo". This is a simplified example taken from my recently written code, does anyone know if I can make it more elegant rather than just doing this?

    public <T extends B> List<Set<T>> foo(Class<T> clazz) {
        List<Set<T>> listSet = (List) mapListSet.get(clazz);

        return listSet;
    }

Any help is hugely appreciated, I have a feeling this code smells really bad and I would love to improve on it.

like image 655
Bartolini Avatar asked Oct 27 '25 02:10

Bartolini


1 Answers

To do what you want to do you have to circumvent the type system a little.

You have to trick the compiler by going through an extra type:

List<Set<T>> listSet = (List<Set<T>>) (Object) mapListSet.get(clazz); // Compiles

The problem is, as racraman notes, that T extends B does not imply that List<Set<T>> extends List<Set<B>>, and since the compiler doesn't see how the cast could ever work it generates an error. It is the same reason as you can't cast, for example String to Number. Since they have no subtype relationship the compiler thinks the cast just can't be right.

It looks like you keep track of the member types of each set at runtime, using a Class as key. It that situation it might be justified to use the above trick.

like image 72
Lii Avatar answered Oct 29 '25 15:10

Lii



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!