In the code below, the type parameter D
can be either a List<Byte>
or a List<List<Byte>>
(it is the third generic parameter in the Fields<?, ?, D>
interface but still I might omit it there - but it is present also in the return type of the method). Can't seem to find a way to tell the compiler this - get Unchecked cast
warnings in the lines marked //*
:
public static <D, K, T extends Enum<T> & Fields<?, ?, D>> List<EnumMap<T, D>>
getEntries(InputStream is, Class<T> fields) throws IOException {
final List<List<Byte>> entries = new ArrayList<List<Byte>>();
// populate "entries"
final boolean hasLists = hasLists(fields);
List<K> daBytes;
if (hasLists) {
daBytes = (List<K>) new ArrayList<EnumMap<T, List<List<Byte>>>>(); //*
} else {
daBytes = (List<K>) new ArrayList<EnumMap<T, List<Byte>>>(); //*
}
final int numOfEntries = entries.size();
for (int currentEntry = 0; currentEntry < numOfEntries; ++currentEntry) {
// add an element in daBytes for this currentEntry
if (hasLists) {
daBytes.add((K) new EnumMap<T, List<List<Byte>>>(fields)); //*
} else {
daBytes.add((K) new EnumMap<T, List<Byte>>(fields)); //*
}
for (T daField : fields.getEnumConstants()) {
List<Byte> field = new ArrayList<Byte>();
// populate "field"
D map = (D) daBytes.get(currentEntry);
if (hasLists) {
List<List<Byte>> fieldEntries = new ArrayList<List<Byte>>();
// populate "fieldEntries"
((EnumMap<T, List<List<Byte>>>) map).put(daField,
fieldEntries); //*
} else {
((EnumMap<T, List<Byte>>) map).put(daField, field); //*
}
}
}
return (List<EnumMap<T, D>>) daBytes; //*
}
If hasLists
is false then I need D to be a List<Byte>
else a List<List<Byte>>
. The daList
variable is a List<EnumMap<T, D>>
. Now it would seem natural (to me) to define :
List<EnumMap<T, D>> daBytes;
But as soon as I do this and change :
if (hasLists) {
daBytes = (List<EnumMap<T, D>>) new ArrayList<EnumMap<T, List<List<Byte>>>>();
}
I get an error :
Cannot cast from
ArrayList<EnumMap<T,List<List<Byte>>>>
toList<EnumMap<T,D>>
Been going round in circles making daBytes an Object, a List<?>
etc but always getting to use either outright casts or generic casts that lead to warnings. There must a way to have this compile cleanly with no casts
>`. It is not possible to represent both with a single generic type, because they have nothing in common except both being Lists.