Home > OS >  Why is "? extends" required here in the type declaration
Why is "? extends" required here in the type declaration

Time:07-21

I noticed that this Java 17 code snippet doesn't compile.

class Foo<T> {
    public Optional<T> getSomeOptional() {
        return Optional.empty();
    }
}

class Bar {
    List<Foo<?>> fooList = new ArrayList<>();
    void bar() {
        List<Optional<?>> list = fooList.stream().map(Foo::getSomeOptional).toList();
    }
}

but changing class Bar to this works.

class Bar {
    List<Foo<?>> fooList = new ArrayList<>();
    void bar() {
        List<? extends Optional<?>> list = fooList.stream().map(Foo::getSomeOptional).toList();
    }
}

Why is ? extends required here in the declaration?

CodePudding user response:

Compilers don't always infer types of complex expressions correctly. In this case, it may help to break them into parts. E.g. in your case, this works:

void bar() {
    Stream<Optional<?>> stream = fooList.stream().map(Foo::getSomeOptional);
    List<Optional<?>> list = stream.toList();
}

CodePudding user response:

This thing you have used is called wildcards.

https://www.geeksforgeeks.org/wildcards-in-java/

Because of Java Type Erasure in the Compile Time, if we don't use a type for our generics then it is considered from the object type, so we use "?" sign or wildcards, by this we basically say that if we pass something in the declaration instead of ?, the compiler should bound the generic to that and don't make it object type.

Note: if you don't bound with anything no matter what type you use, because of java Erasure it's type will become it's super class(the top one).

  • Related