Невозможно создать Map<Class<...>, Parser<...>>
, где ...
-s могут быть любыми, но должны совпадать между ключом и его значением; так что вы не можете заставить компилятор сделать проверку для вас, где получение Class<T>
гарантированно даст вам Parser<T>
. Однако, ваш код сам по себе правильный; вы знаете, что ваш актер корректен, хотя компилятор этого не делает.
Итак, когда вы знаете, что у вас отличное качество, но Java не знает это, что вы можете сделать?
Лучший и безопасный подход заключается в создании определенной части вашего кода, как можно меньшего размера, который отвечает за обработку перевода между проверенной и неконтролируемой логикой и для обеспечения того, чтобы неконтролируемая логика не вызывала каких-либо ошибки. Затем вы просто отмечаете этот код соответствующей аннотацией @SuppressWarnings
. Например, вы можете иметь что-то вроде этого:
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 ...");
}
}
}
Это позволит вам безопасно писать, в вашем примере:
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);
}
Нет никакого способа сделать это без неконтролируемого приведения. Это нормально, пока вы не занимаетесь смешным делом. – Radiodef