So I have a Tuple2
class as follows:
public final class Tuple2<T1, T2> {
private final T1 mItem1;
private final T2 mItem2;
public T1 getItem1() { return mItem1; }
public T2 getItem2() { return mItem2; }
public Tuple2(final T1 pItem1, final T2 pItem2) {
mItem1 = pItem1;
mItem2 = pItem2;
}
public static <TItem1, TItem2> Tuple2<TItem1, TItem2>
Create(final TItem1 pItem1, final TItem2 pItem2) {
return new Tuple2<>(pItem1, pItem2);
}
}
and I'm trying to instantiate a List
of Tuple2
s, but the type inference seems way weird. I would expect I could do something like this:
// doesn't work
// note that Type2 extends Type1, and Type3 extends Type2
final List<Tuple2<String, Class<?>>> list = Arrays.asList(
Tuple2.Create("1", Type1.class),
Tuple2.Create("2", Type2.class),
Tuple2.Create("3", Type3.class)
);
// still doesn't work
final List<Tuple2<String, Class<? extends Type1>>> list = Arrays.asList(
Tuple2.Create("1", Type1.class),
Tuple2.Create("2", Type2.class),
Tuple2.Create("3", Type3.class)
);
Neither of these work if I cast to Class<?>
or to Class<? extends Type1>
either.
What it requires me to do instead is:
final List<Tuple2<String, ? extends Class<? extends Type1>>> list = Arrays.asList(
Tuple2.Create("1", Type1.class),
Tuple2.Create("2", Type2.class),
Tuple2.Create("3", Type3.class)
);
But then if I want to define a reference to one of these Tuple2
s I have to write:
final Tuple2<String, ? extends Class<? extends Type1>> item = list.get(0);
That is one ugly type name... Is there a way to simplify this? Why does it have to be a Tuple2
"of something that extends Class
of something that extends Type1
", rather than simply "of Class
of something"?
The only simpler way I've found is using the Class
raw type, which seems to be discouraged, and needs some casting:
final List<Tuple2<String, Class>> list = Arrays.asList(
Tuple2.Create("1", (Class)Type1.class),
Tuple2.Create("2", (Class)Type2.class),
Tuple2.Create("3", (Class)Type3.class)
);
final Tuple2<String, Class> item = list.get(0);