简体   繁体   中英

Java 8 generics and type inference issue

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?

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));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM