2016-01-08 12 views
5

私が取り組んでいるプロジェクトは、最近Java 7からJava 8に切り替えました。機能ベースのインタフェースをコードベースに導入する候補として、抽象メソッドを1つしか持たないインタフェースを探したいと思います。 (既存のインターフェイスに@FunctionalInterfaceと注釈を付け、java.util.functionのインターフェイスから拡張するか、または単にそれらを置き換えるだけです)。Javaコードベースで単一のメソッドを持つインタフェースを検索するにはどうすればよいですか?

+1

これはIntelliJでの検査として利用できます。この検査のみを持つ検査プロファイルを作成し、プロジェクトで実行します。 –

+0

この変更には、ケースバイケースの分析が必要であり、アノテーションを追加するだけでなく、他の2つのソリューションはいずれも大幅なリファクタリングを必要とします。ライブラリを設計していない場合、ランダの実装をしている間にインターフェイスを非機能的なものに変換すると、コンパイルの問題がすぐに表示されるため、注釈を追加するだけでは大きな価値はありません。 –

答えて

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'のようにどうなりますか?次に、メソッドをフィルタリングする必要があります。また、 'static'メソッドも取り除かなければなりません。あるいは、フィルターが '抽象'メソッドだけを渡すようにしてください。 'Arrays.stream(c.getMethods()) 'の代わりに' stream(spliterator(c.getMethods()、0)、false) 'を使う理由がありますか? – Holger

+0

あなたのコメントで更新されました –

+0

'.filter(m - >!m.isDefault())の代わりに' .filter(m - > Modifier.isAbstract(m.getModifiers() Modifier.isStatic(m.getModifiers())) '? – Holger

関連する問題