Группа захвата дженериков Java
У меня проблемы с правильным использованием групп захвата Java.
Предположим, у меня есть эти классы:
class Foo{}
class Bar{}
interface InterfaceXYZ<T>{
void doSomething(T t);
}
class FooImplementation implements InterfaceXYZ<Foo>{
@Override void doSomething(Foo){}
}
В заключение,
class Delegator<T>{
Delegator(InterfaceXYZ<T> delegate){this.delegate = delegate;}
void doSomething(T t) {
delegate.doSomething(t);
}
private InterfaceXYZ<T> delegate;
}
Проблема в том, что это работает нормально -
FooImplementation fi = new FooImplementation();
Delegator d = new Delegator(fi);
d.doSomething(new Foo());
Это не работает нормально (как и ожидалось) - вызывает исключение во время выполнения
FooImplementation fi = new FooImplementation();
Delegator d = new Delegator(fi);
d.doSomething(new Bar());
Почему не выдает ошибку времени компиляции? Если мне нужно, чтобы он выдавал ошибку времени компиляции, какие изменения мне нужно сделать?
1 ответ
По большей части это правильно, но вам нужно указать часть <...> во время создания экземпляра (или она будет по умолчанию иметь тип raw, что аналогично
Вот как выглядит экземпляр с использованием <...>. Вот, InterfaceXYZ<Foo>
и FooImplementation являются взаимозаменяемыми (поскольку компилятор знает, что FooImplementation является InterfaceXYZ<Foo>
)
Для Фу
InterfaceXYZ<Foo> fi = new FooImplementation();
Delegator<Foo> d = new Delegator<Foo>(fi);
d.doSomething(new Foo());
И для Bar (получение ошибки времени компиляции вместо времени выполнения)
InterfaceXYZ<Bar> fi = new FooImplementation();
Delegator<Bar> d = new Delegator<Bar>(fi);
d.doSomething(new Bar());
Дополнительное примечание:
InterfaceXYZ<?> fi = new FooImplementation();
не будет выдавать ошибку времени компиляции, потому что вы можете сказать добавить фи к List<InterfaceXYZ<?>>
, где InterfaceXYZ<bar>
также действителен и пригоден для использования. Компилятор не может и не будет проверять все возможные способы использования объекта в стеке вызовов, поэтому доверяйте только ошибкам времени компиляции, которые появляются только в контексте текущего компилируемого класса.