ошибка
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return new DefaultLiteProcessScope();
}
}
Правильно
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return (S) new DefaultLiteProcessScope();
}
}
DefaultLiteProcessScope расширяет DefaultLiteProcessScope, но его не нужно приводить? Почему?
Не могли бы вы использовать более короткие названия (несколько букв) для своих классов, чтобы ваш вопрос был понятнее?
S
расширяет DefaultLiteProcessScope
, поэтому вы пытаетесь вернуть экземпляр родительского класса вместо экземпляра дочернего класса.
Причина в том, что код неверный.
public class MyOtherFactory<SubclassOfDefaultLiteProcessScope> {}
сломается, потому что DefaultLiteProcessScope не является SubclassOfDefaultLiteProcessScope.
Вы имеете в виду, что ключевое слово extends не включает себя?
@DavidRicardo Нет, я не это имею в виду. Я имею в виду, что расширения могут быть подклассом. Если S является подклассом DefaultLiteProcessScope, то возвращать DefaultLiteProcessScope неправильно.
Ваш код выдаст ClassCastException
в следующем случае:
class CustomLiteProcessScope extends DefaultLiteProcessScope { ... }
final DefaultLiteProcessScopeFactory<CustomLiteProcessScope> factory = new ...;
А потом:
factory.build(); <-- Exception trying to cast DefaultLiteProcessScope to CustomLiteProcessScope
То, что вы здесь делаете, неправильно. Вы хотите вернуть некоторый подтип DefaultLiteProcessScope
из метода build
. Однако вы жестко кодируете тип возвращаемого значения следующим образом: new DefaultLiteProcessScope()
. Теперь подумайте о слегка надуманном примере, подобном этому.
static class SubType extends DefaultLiteProcessScope {
}
И клиентский код, который следует.
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build();
Теперь, поскольку вы жестко закодировали возвращаемый тип, ваш компилятор не может поручиться за безопасность типов кода. Я хотел, чтобы он возвращал подтип, однако вместо этого вы жестко запрограммировали супертип. Итак, он просит вас добавить явное приведение, что справедливо, не так ли? На самом деле, это приведение не работает во время выполнения, выдавая java.lang.ClassCastException
, поскольку супертип DefaultLiteProcessScope
не может быть приведен к подтипу SubType
.
Как исправить.
Гораздо лучшим подходом было бы передать поставщика вашему методу сборки в качестве аргумента, подобного этому.
static class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build(Supplier<S> s) {
return s.get();
}
}
static interface LiteProcessScopeFactory<S> {
S build(Supplier<S> s);
}
Вот новый код клиента.
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build(SubType::new);
Приведите минимальный воспроизводимый пример. stackoverflow.com/help/минимально-воспроизводимый-пример