2013-05-03 34 views
11

Tôi đang cố gắng sử dụng phản ánh để xác định xem một trôi qua trong lớp thực hiện một giao diện IsWdidget:Làm thế nào để xác định xem một lớp Java thực hiện một giao diện đặc biệt

public boolean isAWidget(Class<?> clzz) { 
    Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName()); 
    Class<?>[] impls = runtimeClass.getInterfaces(); 
    for(Class<?> clz : impls) 
     if(clz.getName().equals(IsWidget.class.getName())) 
      return true; 

    return false; 
} 

Đây có phải là/cách effecient nhất tốt nhất xác định điều này? Tôi cũng thấy một IsWidget.class.isAssignableFrom(Class<?>) phương pháp ...

Trả lời

13

tôi sẽ sử dụng phương pháp isAssignableFrom để xác định xem IsWidget là một superinterface:

return IsWidget.class.isAssignableFrom(clzz); 

Để trích dẫn từ Javadoc liên kết ở trên:

Xác định nếu lớp hoặc giao diện được đại diện bởi đối tượng Lớp này giống hoặc là một siêu lớp hoặc siêu bề mặt của, lớp hoặc giao diện được đại diện bởi tham số Lớp được chỉ định.

1

1) điều này làm cho không có ý nghĩa

Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName()); 

thử điều này với bất kỳ lớp

Class<?> runtimeClass = ClassLoader.getSystemClassLoader().loadClass(clzz.getName()); 
    System.out.println(runtimeClass == clzz); 

bạn sẽ nhận được

true 

vì vậy nếu bạn loại bỏ dòng này và làm việc trực tiếp với clzz nó đã hiệu quả hơn

2) thử này

class X extends Thread { 
} 

public static void main(String[] args) throws ClassNotFoundException { 
    System.out.print(Arrays.toString(X.class.getInterfaces())); 
} 

bạn sẽ nhận được

[] 

này cũng tương tự như những gì func của bạn đang làm, nhưng trong thực tế X thực hiện Runnable

3) và điều này thực sự là giải pháp một dòng hiệu quả để kiểm tra xem một lớp có triển khai giao diện

System.out.print(Runnable.class.isAssignableFrom(X.class)); 

đầu ra

true 
0

Nếu điều đó có hiệu quả, nó sẽ ổn. Bạn cũng có thể thử gọi phương thức cast của lớp Class và thực hiện thử và nắm bắt.

+0

Tính năng này hoạt động nhưng thực sự lạm dụng điểm sử dụng khối thử/nắm bắt. Cộng với ngoại lệ được ném sẽ làm cho cuộc gọi đắt hơn nó phải là (mặc dù tôi không chắc chắn sẽ hiệu quả hơn khi sử dụng sự phản chiếu để xác định giao diện thực hiện) –

1

Bạn có thể sử dụng phương thức getInterfaces() nếu bạn đang có đối tượng Class.

Class c[] = clzz.getInterfaces(); 
    if(Arrays.asList(c).contains(IsWidget.class)) 
    { 
     return true; 
    } 

Phương thức getInterfaces cung cấp cho bạn một mảng Class đại diện cho interfaces. Hoặc bạn cũng có thể sử dụng phương pháp isAssignableFrom như sau:

IsWidget.class.isAssignableFrom(clzz); 

Nếu bạn có một Object bạn có thể sử dụng phương pháp instanceof.

+0

Điều này sẽ xác định nếu 'clzz' là một siêu lớp 'IsWidget'; nó ngược lại. – rgettman

+0

@rgettman: Đã sửa. Cảm ơn bạn đã thông báo. :) –

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