2016-01-08 61 views
5

我的工作項目最近從Java 7切換到Java 8.我希望能夠找到有一個抽象方法作爲導入功能接口到我們的代碼庫的候選人接口。 (註釋現有接口爲@FunctionalInterface,從java.util.function的接口擴展它們,或者可能只是替換它們)。如何搜索具有單一方法的接口的Java代碼庫?

+1

這是可作爲的IntelliJ檢查。創建一個只有這種檢查的檢查配置文件,並在您的項目上運行它。 –

+0

由於這種變化需要逐案分析,除了添加註釋之外,其他兩種解決方案都需要大量的重構,所以我不會去做。如果你沒有設計一個庫,添加註解也沒有提供太多的價值,因爲如果你在將接口轉換爲非函數接口的同時實現了lambda表達式,你會很快看到編譯問題。 –

回答

6

reflections項目能夠找到並返回在類路徑中的所有類。這裏有一個工作示例:

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

這不會幫助你返回到源代碼,並添加註釋,但它會給你一個可以工作的清單。

+0

如果接口重寫'Object'的方法,比如'Comparator'呢?然後,該方法應該被濾除。而'靜態'方法也應該被刪除。或者更好,只要讓過濾器只傳遞'abstract'方法。是否有理由使用'stream(spliterator(c.getMethods(),0),false)'而不是'Arrays.stream(c.getMethods())'? – Holger

+0

您的意見更新 –

+0

爲什麼不'.filter(M - > Modifier.isAbstract(m.getModifiers()))',而不是'.filter(M - > m.isDefault()!)過濾器(M - >! Modifier.isStatic(m.getModifiers()))'? – Holger

相關問題