0

I'm trying to do this:

public interface Foo<T> {
    Stream<String> getAllKeys();
    T getItemByKey(String key);
}

However, it appears that type erasure gets rid of the String, so when I call getAllKeys I get back a raw Stream.

I thought this would work because these aren't methods with the same signature, and the Stream type param is essentially bound which apparently should therefore get compiled to that type.

Is there any way to make this work, or is it a shortcoming of Java generics? Even casting the Stream or its elements doesn't seem to be working well.

lbar
  • 63
  • 6

1 Answers1

2

getAllKeys() will only return a raw Stream if you use a raw Foo type.

If, on the other hand, you use

Foo<Integer> foo = ...

then

foo.getAllKeys()

will return a Stream<String>.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • Yep, overlooked that in the original instantiation, thanks! – lbar Jan 13 '20 at 13:41
  • It made me realy curious. Could you explain why that is the case? Returned type of that method has nothing to do with the generic, does it? Wouldn't declaring the interface without the parametrized type make it possible for the method to return `Stream`? – Amongalen Jan 13 '20 at 13:43
  • @Amongalen that's the behavior specified in the JLS. Are you asking why Java generics were designed this way? – Eran Jan 13 '20 at 13:50