如何在 java 代码库中搜索具有单一方法的接口?

How can I search a java code base for interfaces that have a single method?

我从事的一个项目最近从 Java 7 切换到 Java 8。我希望能够找到具有单个抽象方法的接口作为引入功能接口的候选者进入我们的代码库。 (将现有接口注释为 @FunctionalInterface,从 java.util.function 中的接口扩展它们,或者可能只是替换它们)。

reflections 项目能够在类路径上找到并 return 所有 类。这是一个工作示例:

ReflectionUtils.forNames(new Reflections(new ConfigurationBuilder().setScanners(new SubTypesScanner(false))
                                                                   .addUrls(ClasspathHelper.forClassLoader()))
                         .getAllTypes()).stream()
               .filter(Class::isInterface)
               .collect(toMap(c -> c,
                              c -> Arrays.stream(c.getMethods())
                                         .filter(m -> !m.isDefault())
                                         .filter(m -> !Modifier.isStatic(m.getModifiers()))
                                         .filter(m -> !isObjectMethod(m))
                                         .collect(toSet())))
               .entrySet().stream()
               .filter(e -> e.getValue().size() == 1)
               .sorted(comparing(e -> e.getKey().toString()))
               .map(e -> e.getKey().toString() + " has single method " + e.getValue())//getOnlyElement(e.getValue()))
               .forEachOrdered(System.out::println);

isObjectMethod 助手定义如下:

private static final Set<Method> OBJECT_METHODS = ImmutableSet.copyOf(Object.class.getMethods());
private static boolean isObjectMethod(Method m){
    return OBJECT_METHODS.stream()
                         .anyMatch(om -> m.getName().equals(om.getName()) &&
                                         m.getReturnType().equals(om.getReturnType()) &&
                                         Arrays.equals(m.getParameterTypes(),
                                                       om.getParameterTypes()));
}

这不会帮助您返回源代码并添加注释,但它会为您提供一个工作列表。

根据评论中的要求,完成这项工作所需的导入是:

import static java.util.Comparator.*;
import static java.util.stream.Collectors.*;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Set;

import org.reflections.ReflectionUtils;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;

import com.google.common.collect.ImmutableSet;