Consider the following API method taken from Shiro’s
org.apache.shiro.subject.PrincipalCollection interface but probably present in other libraries as well:
Collection fromRealm(String realmName);
Yes even nowadays there are still libraries that are using raw-types, probably to preserve pre Java 1.5 compatibility?!
If I now want to use this method together with streams or optionals like this:
I get a warning about unchecked conversion and using raw types and that I should prefer using parameterized types.
Type safety: The method collect(Collector) belongs to the raw type Stream. References to generic type Stream<T> should be parameterized
Note: GenericsTest.java uses unchecked or unsafe operations.
As I can’t change the API method’s signature to get rid of this warning I can either annotate with
@SuppressWarnings("unchecked") or simply cast to
Collection<?> like this:
As this cast of course always works I’m wondering why the compilers are not simply treating
Collection<?> but warn about this situation. Adding the annotation or the cast doesn’t improve the code a single bit, but decreases readability or might even shadow actual valid warnings about usage of unparameterized types.
The reason is quite simple:
You may read
Objects from a
Collection<?> the same way as from
Collection. But you can’t add
Objects to a
Collection<?> (The compiler forbids this) whereas to a
Collection you can.
If after the release of Java 5 the compiler had translated every
Collection<?>, then previously written code would not compile anymore and thus would destroy the backward compatibility.