2016-02-23 64 views
6

如果我有爲什麼沒有reflections.getSubTypesOf(Object.class)查找枚舉?

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

那麼這個發現我的枚舉類

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

但這並不

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

是否有什麼原因呢?


重複的例子:

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

枚舉類:

package cupawntae; 

public enum MyEnum { 
} 

輸出:

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

看起來像一個bug發現。請注意,如果枚舉實現了任何接口,它會突然被發現。在bug修復之前,你可以使用例如Google Guava的ClassPath.from(ClassLoader.getSystemClassLoader())。getTopLevelClasses(「cupawntae」)。不是光滑的,而是完成工作。 –

+1

感謝但看起來像它的記錄 - 雖然這是奇怪的接口的事情。你是怎麼發現的?你有沒有在你的目標包裏實現一個接口? – CupawnTae

回答

6

這實際上是documented behaviour,但它無疑不是特別清楚或intuitiv E:

注意,使用構造new Reflections("my.package")時,只能用前綴「my.package」的URL將被掃描,任何傳遞類在其他URL將不會被掃描(例如,如果my.package.SomeClass延伸other.package.OtherClass ,比以後不會被掃描)。在這種情況下使用其他構造,並指定相關的包/網址

編輯:該文檔的later revision說:

確保掃描所有的傳遞性相關的包。例如,假設你的類C擴展B擴展A,並且B和A都位於另一個不是C的包中,那麼當只掃描C的包時 - 那麼查詢A的子類型將返回任何內容(傳遞),但是查詢對於B的子類型返回C(直接)。在這種情況下,請確保先驗地掃描所有相關的軟件包。

在這種情況下java.lang.Enum計數作爲一個傳遞類(如other.package.OtherClass),並且因此不包括在掃描,意味着Enum亞類不包括在內。

同樣,如果我們在問題示例中使Reflections在目標包外擴展某些內容,例如,

public class Reflector extends Exception { 

那麼該類不再在掃描

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

哇,太糟糕了。所以如果你有一個擴展'AbstractList'的專門類,或者你自己的異常,那麼'reflections.getAllTypes()'就不會找到它。真是一團糟。即使這是有意的,它應該以某種方式改變。至少它應該自動通過java.lang和java.util! –

+1

我的天啊。即使你特別包含'java.lang'和'java.util'作爲包,'reflections.getAllTypes()'和'reflections.getSubTypesOf(Object.class)'都不會給你專門的Exception/LIst。所以沒有辦法讓這個圖書館的所有課程都開放,是嗎?多可惜。 –

+1

好的,最後的評論,我會完成。除了已經提到的Guava的'ClassPath'外,還有https://github.com/lukehutch/fast-classpath-scanner。我沒有嘗試過,但看起來很成熟。 –