2016-02-23 14 views
6

Wenn ichWarum findet reflections.getSubTypesOf (Object.class) keine Enums?

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

dann findet diese meine Enum-Klassen

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

aber nicht

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

dies Gibt es einen Grund für?


Reproduzierbare Beispiel:

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 Klasse:

package cupawntae; 

public enum MyEnum { 
} 

Ausgang:

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

wie ein Bug Looks gefunden. Beachten Sie, dass das enum, wenn es eine Schnittstelle implementiert, plötzlich gefunden wird. Bis der Fehler behoben ist, können Sie z. 'ClassPath.from (ClassLoader.getSystemClassLoader()). GetTopLevelClasses (" cupawntae ")' von Google Guava. Nicht so glatt, aber erledigt den Job. –

+1

Danke, aber sieht aus wie es dokumentiert ist - obwohl das an der Schnittstelle Sache seltsam ist. Wie hast du das entdeckt? Haben Sie zufällig eine Schnittstelle in Ihrem Zielpaket implementiert? – CupawnTae

Antwort

6

Dies ist eigentlich documented behaviour, obwohl es wohl nicht besonders klar oder intuitiv e:

bewusst sein, dass, wenn der Konstruktor new Reflections("my.package") verwendet, nur mit dem Präfix urls ‚my.package‘ wird gescannt und alle transitiven Klassen in anderen Urls werden nicht (zum Beispiel gescannt werden, wenn my.package.SomeClass other.package.OtherClass erstreckt , als der spätere wird nicht gescannt). in diesem Fall die anderen Konstrukteure verwenden und die entsprechenden Pakete/Urls angeben

edit: later revision dieser doc sagt:

Sicherstellen, dass alle transitively relevanten Pakete scannen. zum Beispiel, angesichts Ihrer Klasse C erweitert B erweitert A, und sowohl B und A befinden sich in einem anderen Paket als C, wenn nur das Paket von C gescannt wird - dann Abfragen für Untertypen von A gibt nichts (transitive) zurück, sondern abfragen für Untertypen von B gibt C (direkt) zurück. Überprüfen Sie in diesem Fall alle relevanten Pakete a priori.

In diesem Fall java.lang.Enum zählt als transitive Klasse (wie other.package.OtherClass) und in der Scan daher nicht enthalten ist, sind Subklassen von Enum bedeutet nicht enthalten.

In ähnlicher Weise, wenn wir Reflections im Beispiel der Frage erweitern etwas außerhalb des Zielpakets, z.

public class Reflector extends Exception { 

dann die Klasse wird nicht mehr in der Scan-

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

Wow, das ist schrecklich.Wenn Sie also eine spezialisierte Klasse haben, die 'AbstractList' oder Ihre eigene Exception erweitert, wie Sie gezeigt haben, dann wird' reflections.getAllTypes() 'sie NICHT finden. Was für ein Chaos. Auch wenn das beabsichtigt ist, sollte es irgendwie geändert werden. Zumindest sollte es automatisch über java.lang und java.util gehen! –

+1

Oh mein Gott. Auch wenn Sie 'java.lang' und' java.util' ausdrücklich als Pakete verwenden, erhalten Sie weder 'reflections.getAllTypes()' noch 'reflections.getSubTypesOf (Object.class)' die spezielle Exception/LIst. Es gibt also einfach keine Möglichkeit, all deine Klassen mit dieser Bibliothek zu bekommen, oder? Schade. –

+1

Okay, letzter Kommentar und ich werde fertig sein. Außerhalb des bereits erwähnten Guava 'ClassPath' gibt es https://github.com/lukehnutch/fast-classpath-scanner, der das auch tut. Ich habe es nicht ausprobiert, aber es sieht ziemlich reif aus. –

Verwandte Themen