Question

I need to accept a Map that can be either TypeA or TypeB like below.

 Map<Animal, List<TypeA/TypeB>>

How do I declare this? I cannot specify two classes for upper bounds.

 Map<Animal, List<? extends Object>> OR Map<Animal, List<Object>>

is too wide. I wanted to restrict it to TypeA or TypeB

Any better way?

Cannot wrap TypeA and TypeB with interface.

EDIT: From the answers, I understand that, it is not possible with custom types. The follow up questions is, if I just use <? extends Object>, how should I check the type of ? is either TypeA or TypeB. Should I use instanceof? Code sample?

Was it helpful?

Solution

The obvious solution would be to introduce a supertype of TypeA and TypeB that contains the behaviour you require.

A different approach would be to use an adapter. To quote from ye olde Gang of Four book:

Convert the interface of a class into another interface clients expect. Adapter lets class work together that couldn't otherwise because of incompatible interfaces.

So here we would introduce an adapter type (only with a better name than this).

interface Ab {
    void someOp();
}

Then we can wrap existing objects.

public static Ab asAb(final TypeA obj) {
    return new Ab() {
        public void someOp() {
            obj.someOp();
        }
    };
}

The map can use the adapter type as the value.

Map<Animal, List<Ab>>

When I have come across this issue in existing code, it has been because the map actually contains two disjoint maps. The easy solution there is to use two maps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top