A project I work on has recently switched from Java 7 to Java 8. I'd like to be able to find interfaces that have a single abstract method as candidates for introducing functional interfaces into our code base. (Annotating existing interfaces as @FunctionalInterface
, extending them from the interfaces in java.util.function
, or possibly just replacing them).
The reflections project is able to locate and return all classes on the classpath. Here's a working example:
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);
The isObjectMethod
helper is defined like this:
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()));
}
This doesn't help you go back to the source code and add the annotations, but it'll give you a list to work from.
As requested in the comments, the imports needed to make this work are:
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;
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