Un progetto su cui lavoro è passato da Java 7 a Java 8. Mi piacerebbe poter trovare interfacce che abbiano un unico metodo astratto come candidati per l'introduzione di interfacce funzionali nel nostro codice base. (Annotando le interfacce esistenti come @FunctionalInterface
, estendendole dalle interfacce in java.util.function
o eventualmente semplicemente sostituendole).Come posso cercare una base di codice Java per le interfacce che hanno un singolo metodo?
risposta
Il progetto reflections è in grado di individuare e restituire tutte le classi sul classpath. Ecco un esempio di lavoro:
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);
Il isObjectMethod
aiutante si definisce in questo modo:
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()));
}
Questo non aiuta si torna al codice sorgente e aggiungere le annotazioni, ma ti do una lista da cui lavorare.
Cosa succede se l'interfaccia sovrascrive un metodo 'Object', come fa il' Comparator'? Quindi, il metodo dovrebbe essere filtrato. E anche i metodi 'static' dovrebbero essere rimossi. O meglio, lascia che il filtro passi solo i metodi 'abstract'. E c'è un motivo per usare 'stream (spliterator (c.getMethods(), 0), false)' invece di 'Arrays.stream (c.getMethods())'? – Holger
aggiornato con i tuoi commenti –
Perché non '.filter (m -> Modifier.isAbstract (m.getModifiers()))' invece di '.filter (m ->! M.isDefault()). Filter (m ->! Modifier.isStatic (m.getModifiers())) '? – Holger
- 1. Le interfacce PHP hanno proprietà?
- 2. Perché hanno deciso di rendere le interfacce "Operazioni opzionali"
- 3. Come posso richiedere un argomento di metodo in Java per implementare più interfacce?
- 4. Come simulare un singolo metodo in java
- 5. Le interfacce di un singolo implementatore per l'unità testano un antipattern?
- 6. Un metodo java che implementa un metodo di classe base restituisce una classe ereditata?
- 7. Gli oggetti modello hanno interfacce?
- 8. Una metologia che consente un singolo codice Java che copre molte versioni differenti?
- 9. Privilegi di amministratore per un singolo metodo
- 10. Java ha inventato le interfacce?
- 11. Come posso cercare un pacchetto hackage per una funzione?
- 12. Posso creare interfacce tipo Java in Perl?
- 13. utilizzando jQuery per cercare una stringa di codice HTML
- 14. In che modo le interfacce verranno sostituite/aumentate dalle chiusure in Java?
- 15. Come cercare un codice postale da una coordinata GPS?
- 16. Più interfacce da un singolo servizio WCF?
- 17. Se le interfacce non hanno costruttori, la classe Object è una super classe di un'interfaccia?
- 18. Cercare un modo conveniente per chiamare Java da C++
- 19. Dovresti sempre codificare le interfacce in Java
- 20. Java - Interfacce di implementazione
- 21. Non può implementare due interfacce che hanno lo stesso nome del metodo
- 22. Come è possibile eseguire le ricerche IDE Java eseguite per riferimenti al metodo a livello di codice?
- 23. Come posso cercare (escape) un segno di dollaro usando ack?
- 24. Le rotaie hanno un opposto di `parameterize` per le stringhe?
- 25. Parametri facoltativi per le interfacce
- 26. Java: estrae le interfacce solo per il test
- 27. Utilizzare le interfacce Clojure in un progetto di libreria Java
- 28. Espressione ternario con le interfacce come classe base
- 29. Dovrei cercare di evitare metodo sincronizzato static
- 30. Che cos'è una "forma di funzione" rispetto alle interfacce funzionali in Java 8?
Questo è disponibile come ispezione in IntelliJ. Creare un profilo di ispezione che abbia solo questa ispezione ed eseguirlo sul progetto. –
Poiché questo cambiamento richiederebbe un'analisi caso per caso e, a parte per aggiungere l'annotazione, le altre due soluzioni richiedono entrambi un refactoring significativo, non ci andrei. Se non si sta progettando una libreria, l'aggiunta dell'annotazione non fornisce molto valore, poiché si vedrebbero rapidamente problemi di compilazione se si trasforma un'interfaccia in una non funzionale mentre ha implementazioni lambda. –