2016-02-23 14 views
6

Se hoPerché reflections.getSubTypesOf (Object.class) non trova enumerazioni?

Reflections reflections = new Reflections("my.package", classLoader, new SubTypesScanner(false)); 

allora questo trova il mio Enumera classi

Set<Class<? extends Enum>> enums = reflections.getSubTypesOf(Enum.class); 

ma questo non

Set<Class<?>> classes = reflections.getSubTypesOf(Object.class); 

C'è una ragione per questo?


esempio riproducibile:

package cupawntae; 

import org.reflections.Reflections; 
import org.reflections.scanners.SubTypesScanner; 

public class Reflector { 
    public static void main(String[] args) { 
     Reflections reflections = new Reflections("cupawntae", Reflector.class.getClassLoader(), new SubTypesScanner(false)); 
     System.out.println("Objects: " + reflections.getSubTypesOf(Object.class)); 
     System.out.println("Enums: " + reflections.getSubTypesOf(Enum.class)); 
     System.out.println("Enum's superclass: " + Enum.class.getSuperclass()); 
    } 
} 

Enum classe:

package cupawntae; 

public enum MyEnum { 
} 

uscita:

Objects: [class cupawntae.Reflector] 
Enums: [class cupawntae.MyEnum] 
Enum's superclass: class java.lang.Object 
+1

Sembra come un insetto. Notare che se l'enumerazione implementa qualsiasi interfaccia, viene improvvisamente trovata. Fino a quando il bug non viene corretto, puoi utilizzare ad es. 'ClassPath.from (ClassLoader.getSystemClassLoader()). GetTopLevelClasses (" cupawntae ")' di Google Guava. Non così sdolcinato, ma fa il lavoro. –

+1

Grazie, ma sembra che sia documentato - anche se è strano riguardo all'interfaccia. Come l'hai scoperto? Hai per caso implementato un'interfaccia all'interno del tuo pacchetto target? – CupawnTae

risposta

6

Questo è in realtà documented behaviour, anche se è probabilmente non è particolarmente chiaro o intuitiv e:

essere consapevoli che quando si utilizza il costruttore new Reflections("my.package"), URL solo con prefisso 'my.package' viene scandito e qualsiasi classe transitivi in ​​altri URL non sarà esaminato (per esempio se my.package.SomeClass estende other.package.OtherClass , che il successivo non verrà scansionato). in questo caso utilizzare gli altri costruttori e specificare i relativi pacchetti/URL

edit: later revision di quel dottore dice:

Assicurarsi di eseguire la scansione di tutti i pacchetti transitivamente rilevanti. per esempio, data la tua classe C estende B estende A, e sia B che A si trovano in un altro pacchetto rispetto a C, quando viene scansionato solo il pacchetto di C - quindi l'interrogazione per i sottotipi di A non restituisce nulla (transitivo), ma l'interrogazione per i sottotipi di B restituisce C (diretto). In tal caso, accertarsi di esaminare tutti i pacchetti pertinenti a priori.

In questo caso java.lang.Enum conta come una classe transitiva (come other.package.OtherClass), e non è pertanto incluso nella scansione, il che significa sottoclassi di Enum non sono inclusi.

Analogamente, se si effettua Reflections nell'esempio della domanda, estendere qualcosa al di fuori del pacchetto di destinazione, ad es.

public class Reflector extends Exception { 

allora la classe non si trova più nella scansione

Objects: [] 
Enums: [class cupawntae.MyEnum] 
Enum's superclass: class java.lang.Object 
+1

Wow, è terribile.Quindi se avrai una classe specializzata che estenderà 'AbstractList', o la tua Eccezione, come hai mostrato, allora 'reflections.getAllTypes()' NON lo troverà. Che casino. Anche se è destinato, dovrebbe essere cambiato in qualche modo. Almeno dovrebbe andare su java.lang e java.util automaticamente! –

+1

Oh mio dio. Anche se includi in modo specifico 'java.lang' e' java.util' come pacchetti, né 'reflections.getAllTypes()' né 'reflections.getSubTypesOf (Object.class)' ti daranno l'eccezione Special/List. Quindi non c'è modo di ottenere tutte le tue lezioni con questa libreria, vero? Che peccato. –

+1

Ok, ultimo commento e sarò fatto. Al di fuori del già menzionato 'ClassPath' di Guava, c'è anche https://github.com/lukehutch/fast-classpath-scanner che fa altrettanto. Non l'ho provato, ma sembra abbastanza maturo. –