Java 8泛型和类型推断问题

use*_*663 5 java generics type-inference java-stream

我想转换这个:

static Set<String> methodSet(Class<?> type) {
    Set<String> result = new TreeSet<>();
    for(Method m : type.getMethods())
        result.add(m.getName());
    return result;
}
Run Code Online (Sandbox Code Playgroud)

哪个编译得很好,更现代的Java 8流版本:

static Set<String> methodSet2(Class<?> type) {
    return Arrays.stream(type.getMethods())
        .collect(Collectors.toCollection(TreeSet::new));
}
Run Code Online (Sandbox Code Playgroud)

这会产生错误消息:

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
Run Code Online (Sandbox Code Playgroud)

我可以看到为什么编译器会遇到这个问题---没有足够的类型信息来确定推理.我看不到的是如何解决它.有人知道吗?

Tun*_*aki 11

错误消息不是特别清楚,但问题是您没有收集方法的名称,而是收集方法本身.

换句话说,您缺少Method从其名称到其名称的映射:

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));
}
Run Code Online (Sandbox Code Playgroud)