I'm trying to convert this:
static Set<String> methodSet(Class<?> type) {
Set<String> result = new TreeSet<>();
for(Method m : type.getMethods())
result.add(m.getName());
return result;
}
Which compiles just fine, to the more modern Java 8 streams version:
static Set<String> methodSet2(Class<?> type) {
return Arrays.stream(type.getMethods())
.collect(Collectors.toCollection(TreeSet::new));
}
Which produces an error message:
error: incompatible types: inference variable T has incompatible bounds
.collect(Collectors.toCollection(TreeSet::new));
^
equality constraints: String,E
lower bounds: Method
where T,C,E are type-variables:
T extends Object declared in method <T,C>toCollection(Supplier<C>)
C extends Collection<T> declared in method <T,C>toCollection(Supplier<C>)
E extends Object declared in class TreeSet
1 error
I can see why the compiler would have trouble with this --- not enough type information to figure out the inference. What I can't see is how to fix it. Does anyone know?
Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.
Type safety is verified at compile time, and runtime is unfettered by the generic type system. In turn, this imposed the restriction that generics could only work over reference types, since Object is the most general type available, and it does not extend to primitive types.
A Generic class can have muliple type parameters.
The error message is not particularly clear but the problem is that you are not collecting the name of the methods but the methods themselves.
In other terms, you are missing the mapping from the Method
to its name:
static Set<String> methodSet2(Class<?> type) {
return Arrays.stream(type.getMethods())
.map(Method::getName) // <-- maps a method to its name
.collect(Collectors.toCollection(TreeSet::new));
}
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