Вызываемый метод внутреннего универсального класса не распознает универсальный тип

Я борюсь со следующим внутренним классом, «наследующим» универсальный параметр T от внешнего класса. Следующие строки ошибочны:

String string = "string";
new OuterClass<>()
    .inner(string)
    .call(s -> s.length());       // Cannot resolve method 'length' in 'Object'

Минимальный и воспроизводимый пример этих классов:

public class OuterClass<T> {

    public InnerClass<T> inner(T object) {
        return new InnerClass<>(object);
    }

    @AllArgsConstructor(access = AccessLevel.PRIVATE)
    public static final class InnerClass<U> {

        U object;

        public final void call(Consumer<U> consumer) {
            consumer.accept(object);
        }
    }
}

Почему это происходит? Как я должен указать универсальный параметр через создание внутреннего класса?

Всего 1 ответ


По сути, это потому, что вывод типа в <> не учитывает последующие методы, которые вы объединяете в цепочку.

Например, это создает ArrayList<Object> :

new ArrayList<>().add("");

Если я вставлю слово String внутри <> , IntelliJ не будет жаловаться на то, что слово String является избыточным.

Точно так же это производит ошибку:

OuterClass<String>.InnerClass i = new OuterClass<>().inner(string);

Потому что правая часть создает OuterClass<Object>.Inner , а левая часть - OuterClass<String>.InnerClass .

Чтобы это исправить, вам нужно указать универсальный параметр:

new OuterClass<String>()
    .inner(string)
    .call(s -> s.length()); 

Что касается вашего редактирования, отредактированный inner метод все еще зависит от универсального типа Outer , который не может быть выведен правильно.

Вы можете сделать созданный объект Inner независимым от универсального типа Outer , добавив еще один универсальный параметр:

public <U> InnerClass<U> inner(U object) {
    return new InnerClass<>(object);
}

Есть идеи?

10000