It is impossible to create Map<Class<...>, Parser<...>> , where ... -s can be any, but must match between the key and its value; so you cannot force the compiler to do a check for you, where getting a Class<T> guaranteed to give you a Parser<T> . However, your code itself is correct; You know that your actor is correct, although the compiler does not.
So, when you know that your actor is correct, but Java does not know this, what can you do?
The best and safest approach is to create a specific fragment of your code, as small as possible, which is responsible for processing the translation between the checked and uncontrolled logic and to ensure that the uncontrolled logic does not cause @SuppressWarnings you simply mark this code with the corresponding @SuppressWarnings annotation. For example, you may have something like this:
public abstract class Parser<T> { private final Class<T> mType; protected Parser(final Class<T> type) { this.mType = type; } public final Class<T> getType() { return mType; } @SuppressWarnings("unchecked") public final <U> Parser<U> castToParserOf(final Class<U> type) { if (type == mType) { return (Parser<U>) this; } else { throw new ClassCastException("... useful message ..."); } } }
This will allow you to write safely in your example:
public <T> void addParser(final Parser<T> parser) { parsers.put(parser.getType(), parser); } private <T> Parser<T> parserFor(final Class<T> type) { return parsers.get(type).castToParserOf(type); }
source share