2016-01-08 18 views
5

Üzerinde çalıştığım bir proje yakın zamanda Java 7'den Java 8'e geçmiştir. İşlevsel arayüzleri kod tabanımıza yerleştirmek için aday olarak tek bir soyut yönteme sahip arayüzleri bulmak istiyorum. (Mevcut arabirimleri @FunctionalInterface olarak ekleyerek, java.util.function numaralı arabirimden genişleterek veya yalnızca değiştirerek).Tek bir yöntemi olan arabirimler için java kod tabanını nasıl arayabilirim?

+1

Bu, IntelliJ'de bir inceleme olarak kullanılabilir. Yalnızca bu incelemeye sahip bir denetim profili oluşturun ve projenizde çalıştırın. –

+0

Bu değişiklik, duruma göre bir analiz gerektireceğinden ve ek açıklama eklemenin yanı sıra, diğer 2 çözümün de her ikisinin de önemli bir refactoring gerektirmesi gerekir. Bir kütüphane tasarlamıyorsanız, ek açıklama eklemek çok fazla bir değer sağlamamaktadır, çünkü lambda uygulamalarına sahip bir arabirimi işlevsel olmayan birine dönüştürürseniz derleme sorunlarını hızlı bir şekilde göreceksiniz. –

cevap

6

reflections proje bulmak ve üzerinde sınıf tüm sınıfları iade edebilir.

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 yardımcı böyle tanımlanır::

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

Bu, geri kaynak kodu gidip, açıklama ekleme yardımcı olmuyor, ama size vereceğiz İşte çalışan bir örnektir çalışmak için bir liste.

+0

Arayüz, "Karşılaştırıcı" gibi bir "Nesne" yöntemini geçersiz kılarsa ne olur? Daha sonra, yöntem filtrelenmelidir. Ve 'statik 'yöntemleri de kaldırılmalıdır. Ya da daha iyisi, filtrenin sadece 'soyut' yöntemlerden geçmesine izin verin. Arrays.stream (c.getMethods()) 'yerine 'stream (spliterator (c.getMethods(), 0), false' kullanmak için bir neden var mı? (-> Modifier.isAbstract (m.getModifiers()) m) 'yerine' .filter ait – Holger

+0

yorumlarınızla birlikte –

+0

Neden '.filter güncellenmiş (m -> m.isDefault()!) (Filtrelemek m -.>! Modifier.isStatic (m.getModifiers())) '? – Holger

İlgili konular