Можно ли унифицировать захват в Java generics в объявлениях типов?

Рассмотрим следующую функцию Java:

public void foo(Class<? extends Exception> cl, List<? extends Exception> ls) throws Exception {
    ls.add(cl.newInstance());
}

Это не работает, поскольку захват типов cl и ls не унифицирован и может, действительно, ссылаться на разные типы. Если бы эта функция компилировалась, я мог бы вызвать ее как foo(NullPointerException.class, new List()), что было бы незаконно.

Мы можем исправить это, очевидно, путем унификации захвата типов, например, так:

public <T extends Exception> void foo(Class<T> cl, List<T> ls) throws Exception {
    ls.add(cl.newInstance());
}

Теперь эта функция работает, как и ожидалось. Таким образом, переходим к моему вопросу: Есть ли способ унифицировать захват типов в рамках одного объявления типа?

Например, я часто сталкиваюсь с тем, что мне нужна карта, которая сопоставляет классы с их экземплярами. Единственный способ, который я могу придумать в настоящее время, это иметь сопровождающую функцию, которая делает непроверенные приведения:

private Map<Class<? extends Foo>, ? extends Foo> map = ...;
@SuppressWarnings("unchecked")
private <T extends Foo> T getFoo(Class<T> cl) {
    return((T)map.get(cl));
}

Но было бы, конечно, приятнее не подавлять предупреждения, а просто заставить компилятор понять, что два приведения типа в объявлении типа map должны быть одинаковыми, а затем просто сделать map публичным. Например, если бы я мог иметь объявление, подобное следующему:

<T extends Foo> Map<Class<T>, T> map = ...;

Очевидно, что это неправильный синтаксис, но мой вопрос сводится к следующему: Есть ли какой-нибудь правильный синтаксис, который позволил бы мне сделать что-то подобное?

5
задан Dolda2000 8 February 2012 в 21:27
поделиться