2016-02-23 13 views
6

Nếu tôi cóTại sao không reflections.getSubTypesOf (Object.class) tìm enums?

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

thì đây thấy lớp enum tôi

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

nhưng điều này không

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

Có một lý do cho việc này?


dụ tái sản xuất:

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 lớp:

package cupawntae; 

public enum MyEnum { 
} 

Output:

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

Trông giống như một lỗi. Lưu ý rằng nếu enum thực hiện bất kỳ giao diện, nó đột nhiên được tìm thấy. Cho đến khi lỗi được khắc phục, bạn có thể sử dụng ví dụ: 'ClassPath.from (ClassLoader.getSystemClassLoader()). GetTopLevelClasses (" cupawntae ")' của Google ổi. Không phải là slick, nhưng được công việc làm. –

+1

Cảm ơn nhưng có vẻ như nó được ghi lại - mặc dù điều đó lạ về điều giao diện. Làm thế nào bạn phát hiện ra điều đó? Bạn có cơ hội thực hiện một giao diện bên trong gói nhắm mục tiêu của mình không? – CupawnTae

Trả lời

6

Đây thực sự là documented behaviour, mặc dù nó cho là không đặc biệt rõ ràng hoặc intuitiv e:

lưu ý rằng khi sử dụng constructor new Reflections("my.package"), chỉ URL với tiền tố 'my.package' sẽ được quét, và bất kỳ lớp học bắc cầu trong các url khác sẽ không được quét (ví dụ nếu my.package.SomeClass kéo dài other.package.OtherClass , so với sau sẽ không được quét). trong trường hợp đó sử dụng các nhà thầu khác và chỉ định các gói/url liên quan

chỉnh sửa: later revision của doc nói rằng:

Hãy chắc chắn để quét tất cả các gói transitively có liên quan. Ví dụ: , cho lớp C mở rộng B mở rộng A, và cả B và A được đặt trong gói khác so với C, khi chỉ gói C được quét - sau đó truy vấn các loại phụ A trả về không có gì (chuyển tiếp), nhưng truy vấn đối với các loại B trả về C (trực tiếp). Trong trường hợp đó, hãy đảm bảo quét tất cả các gói có liên quan trước tiên.

Trong trường hợp này java.lang.Enum được tính là một lớp bắc cầu (như other.package.OtherClass), và do đó không được đưa vào quá trình quét, có nghĩa là lớp con của Enum không được tính.

Tương tự, nếu chúng ta tạo Reflections trong ví dụ của câu hỏi, hãy mở rộng thứ gì đó bên ngoài gói đích, ví dụ:

public class Reflector extends Exception { 

sau đó các lớp không còn được tìm thấy trong quá trình quét

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

Chà, thật khủng khiếp.Vì vậy, nếu bạn sẽ có một lớp chuyên biệt mở rộng 'AbstractList', hoặc ngoại lệ của riêng bạn, như bạn đã chỉ ra, thì' reflections.getAllTypes() 'sẽ không tìm thấy nó. Thật là một mớ hỗn độn. Ngay cả khi đó là dự định, nó sẽ được thay đổi bằng cách nào đó. Ít nhất nó nên đi qua java.lang và java.util tự động! –

+1

Ôi trời ơi. Thậm chí nếu bạn đặc biệt bao gồm 'java.lang' và' java.util' làm các gói, không phải 'reflections.getAllTypes()' cũng không phải 'reflections.getSubTypesOf (Object.class)' sẽ cung cấp cho bạn ngoại lệ/LIST chuyên biệt. Vì vậy, không có cách nào để có được tất cả các lớp học của bạn với thư viện này, là có? Xấu hổ làm sao. –

+1

Ok, bình luận cuối cùng và tôi sẽ hoàn thành. Bên ngoài 'ClassPath' của Guava đã đề cập, có https://github.com/lukehutch/fast-classpath-scanner cũng thực hiện điều này. Tôi đã không thử nó, nhưng nó trông khá trưởng thành. –

Các vấn đề liên quan