Почему это все еще нужно бросать в java?

ошибка

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, но его не нужно приводить? Почему?

Приведите минимальный воспроизводимый пример. stackoverflow.com/help/минимально-воспроизводимый-пример

Ravindra Ranwala 12.05.2022 09:53

Не могли бы вы использовать более короткие названия (несколько букв) для своих классов, чтобы ваш вопрос был понятнее?

Bohemian 12.05.2022 09:56
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
2
78
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

S расширяет DefaultLiteProcessScope, поэтому вы пытаетесь вернуть экземпляр родительского класса вместо экземпляра дочернего класса.

Причина в том, что код неверный.

public class MyOtherFactory<SubclassOfDefaultLiteProcessScope> {}

сломается, потому что DefaultLiteProcessScope не является SubclassOfDefaultLiteProcessScope.

Вы имеете в виду, что ключевое слово extends не включает себя?

David Ricardo 12.05.2022 10:45

@DavidRicardo Нет, я не это имею в виду. Я имею в виду, что расширения могут быть подклассом. Если S является подклассом DefaultLiteProcessScope, то возвращать DefaultLiteProcessScope неправильно.

kutschkem 12.05.2022 11:57

Ваш код выдаст 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);

Другие вопросы по теме