Today I tried to reference a constructor in generic. Why is it incorrect?
import java.util.Collection;
import java.util.function.Supplier;
class Foo<R extends Collection<Integer>> {
Supplier<R> supplier = R::new; // Compiler error!
}
Error text:
java: unexpected type
required: class or array
found: type parameter R
Is it because of type erasure? Or maybe I'm doing it wrong?
At compile time, all you know about R
is its bound; that it is a subtype of Collection<Integer>
. You don't know what class R
corresponds to. But you are trying to reference a constructor -- and to reference a constructor, you have to know exactly what class you're trying to construct. All of the following would fail to work for the same reason: it is not known what R is, and you need to know what R is to call its constructor.
Supplier<R> supplier = R::new
Supplier<R> supplier = () -> new R();
R r = new R();
The same would be true even if R were declares as <R extends ArrayList<String>>
. In this case, you'd know that R extends ArrayList<String>
, but you still don't know what class it is!
If you were trying to access a virtual member of Collection<Integer>
, it would work:
ToIntFunction<R> sizer = R::size;
because, whatever R
is, it must have a size()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With