Skip to content

Instantly share code, notes, and snippets.

@odrotbohm
Created March 29, 2018 07:52
Show Gist options
  • Save odrotbohm/a52c430f84d4f70fcda6cb494dc15981 to your computer and use it in GitHub Desktop.
Save odrotbohm/a52c430f84d4f70fcda6cb494dc15981 to your computer and use it in GitHub Desktop.
public class Sample {
public static void main(String[] args) {
Foo<? extends Bar<?>> foo = new Foo<>();
// Compiles
Iterable<?> first = foo.someMethod();
DedicatedWrapper<? extends Bar<?>> dedicatedWrapper = foo.someOtherMethod();
// Does not compile:
// Type mismatch: cannot convert from Iterable<Sample.SomeWrapper<capture#2-of ? extends Sample.Bar<?>>>
// to Iterable<Sample.SomeWrapper<? extends Sample.Bar<?>>>
Iterable<SomeWrapper<? extends Bar<?>>> second = foo.someMethod();
}
static class Foo<B extends Bar<B>> {
Iterable<SomeWrapper<B>> someMethod() {
return Collections.emptySet();
}
DedicatedWrapper<B> someOtherMethod() {
return null;
}
}
interface Bar<B extends Bar<B>> {}
interface SomeWrapper<B extends Bar<B>> {}
interface DedicatedWrapper<B extends Bar<B>> extends Iterable<SomeWrapper<B>> {}
}
@philwebb
Copy link

philwebb commented Mar 29, 2018

I think it boils down to the fact that the compiler doesn't know that the first and second ? in this line refer to the same thing Foo<? extends Bar<?>> foo = new Foo<>();

In the past when I've had this kind of problem I've extracted the method and added a real generic:

public static void main(String[] args) {
	typed();
}

private static <T extends Bar<T>> void typed() {
	Foo<T> foo = new Foo<>();

	// Compiles
	Iterable<?> first = foo.someMethod();
	DedicatedWrapper<T> dedicatedWrapper = foo.someOtherMethod();

	// Compiles
	Iterable<SomeWrapper<T>> second = foo.someMethod();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment