Я собираюсь создать фабрику, которая создает объекты определенного типа T, который расширяет определенный класс A и другой интерфейс I. Однако T не должен быть известен. Вот минимальное количество объявлений:
public class A { }
public interface I { }
Это фабричный метод:
public class F {
public static <T extends A & I> T newThing() { /*...*/ }
}
Это компилирует все нормально.
Когда я пытаюсь использовать этот метод, следующее работает нормально:
A $a = F.newThing();
...в то время как это не работает:
I $i = F.newThing();
Компилятор жалуется:
Несоответствие границ: универсальный метод newThing() типа F не применимо для аргументов (). Выведенный тип I&A не является допустимой заменой ограниченного параметра
. Я не могу понять, почему.Четко сказано, что «newThing возвращает что-то определенного типа T, который расширяет класс A и реализует интерфейс I». При присвоении A все работает (поскольку T расширяет A), а при присвоении I нет (из-за чего?, ясно, что возвращаемая вещь является и A , и . ] an I)
Также: при возврате объекта, скажем, B типа класс B extends A реализует I
, мне нужно привести его к возвращаемому типу T, хотя B соответствует границам:
<T extends A & I> T newThing() {
return (T) new B();
}
Однако компилятор не выдает никаких предупреждений типа UncheckedCast и т.п.
Итак, мой вопрос:
--
РЕДАКТИРОВАТЬ: Вот полный фрагмент кода, который полностью работает с использованием Eclipse 3.7, проект настроен для JDK 6:
public class F {
public static class A { }
public static interface I { }
private static class B extends A implements I { }
public static <T extends A & I> T newThing() {
return (T) new B();
}
public static void main(String... _) {
A $a = F.newThing();
// I $i = F.newThing();
}
}
РЕДАКТИРОВАТЬ: Вот полный пример с методами и вызовами, которые работает во время выполнения :
public class F {
public static class A {
int methodA() {
return 7;
}
}
public static interface I {
int methodI();
}
private static class B extends A implements I {
public int methodI() {
return 12;
}
}
public static <T extends A & I> T newThing() {
return (T) new B();
}
public static void main(String... _) {
A $a = F.newThing();
// I $i = F.newThing();
System.out.println($a.methodA());
}
}