I'm refactoring someone else's code and They use the type Enum<?>
in several places. It would be a huge pain to get rid of it, and it seems like it should be compatible with a non-generic Java Enum type declaration since they both having nothing to say about the type parameter to the generic type.
I've created this code snippet to demonstrate the problem that has the compile errors noted in the comments:
enum Shapes {
SQUARE,
CIRCLE
};
enum Colors {
RED,
BLUE,
GREEN
};
public void testEnumConversions() throws Exception {
List<Enum<?>> colors = ImmutableList.<Enum<?>>of(Colors.RED, Colors.GREEN, Shapes.SQUARE);
List<Enum> colors2 =
ImmutableList.<Enum<?>>of(Colors.RED, Colors.GREEN); // incompatible types
List<Enum> colors3 =
(List<Enum>)ImmutableList.<Enum<?>>of(Colors.RED, Colors.GREEN); // inconvertible types
List<Enum> colors4 = ImmutableList.<Enum>of(Colors.RED, Colors.GREEN, Shapes.SQUARE);
List<Enum<?>> colors5 = ImmutableList.of(Colors.RED, Colors.GREEN, Shapes.SQUARE);
List<Enum> colors6 =
ImmutableList.of(Colors.RED, Colors.GREEN, Shapes.SQUARE); // incompatible types;
}
Why isn't List<Enum<?>>
compatible with List<Enum>
? They seem identical to me.
Because everything doesn't say the same as something.
Same with Comparable
. Comparable
is Comparable<Object>
, so it must be comparable to everything. Comparable<?>
says "there is something I can compare it with, but I don't know what.
Same here: Enum
is "Enumeration of everything". Whereas Enum<?>
is "Enumeration of something that I do not know".
This brings us to the difference of List<Enum>
to List<Enum<?>>
. The first can contain or take enums of arbitrary type. For the latter, all elements must agree.
I strongly advise against either. Generics are a powerful tool to avoid programming errors. They make your life easier. So understand them, and use them to your advantage. So here, you should be using List<Shapes>
and List<Colors>
.