2011-11-07 35 views
29

tôi rất bối rối ...không thể cast để giao diện thực hiện

Tôi có một lớp học mà trực tiếp thực hiện một giao diện:

public class Device implements AutocompleteResult 
{...} 

Đây là bằng chứng cho thấy tôi đang nhìn vào bên phải biến:

Object match = ...; 
log.debug(match.getClass()); // Outputs 'Device' 
log.debug(match.getClass().getInterfaces()[0]); // Outputs 'AutocompleteResult' 

Tuy nhiên, khi tôi cố gắng đúc một thể hiện của lớp để giao diện:

AutocompleteResult result = (AutocompleteResult) match; 

Tôi nhận được một ClassCastException!

ClassCastException: Device cannot be cast to AutocompleteResult 

Ngoài ra, isAssignableFrom lợi nhuận sai và tôi không chắc chắn lý do tại sao:

log.debug(AutocompleteResult.class.isAssignableFrom(Device.class)); 

từ doc:

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

Tôi không phải lúc nào cũng có thể truyền một đối tượng đến giao diện mà lớp của nó triển khai?

Cảm ơn.

+0

Có, bạn nên! (và bạn thậm chí không cần diễn viên rõ ràng.) Vui lòng đăng một số mã ví dụ độc lập thể hiện sự cố. –

Trả lời

54

Điều này có thể xảy ra nếu hai trình nạp lớp khác nhau tải một lớp có tên là AutocompleteResult.

Hai lớp này sau đó được coi là các lớp hoàn toàn khác nhau, ngay cả khi chúng có cùng một gói và tên (và thậm chí cả việc triển khai/trường/phương pháp).

Nguyên nhân phổ biến cho việc này là nếu bạn sử dụng một số loại hệ thống plugin và cả các lớp cơ sở của bạn và các lớp plugin cung cấp cùng một lớp.

Để kiểm tra các vấn đề này in giá trị được trả về bởi Class.getClassLoader() trên cả hai lớp vi phạm (ví dụ: lớp của giao diện được thực hiện bởi Device kết quả của AutocompleteResult.class).

+1

wow, cảm ơn! tôi đã rách tóc ra khỏi cái này. tôi sẽ cố giải quyết vấn đề nạp lớp ngay bây giờ ... – pstanton

+3

+1: Thử 'log.debug (match.getClass(). getInterfaces() [0] .getClassLoader()); log.debug (AutocompleteResult.class.getClassLoader()) ' –

+0

Vấn đề của tôi là tôi đã nhập sai lớp và điều này đã giúp tôi xác định rằng:' Class [] interfaces = match.getClass(). getInterfaces(); cho (int i = 0; i toobsco42

0

AKA khi Java dường như không Java.

tôi trúng vấn đề này thời gian gần đây với Play Khung 2.6.3, những gì đã giúp tôi được điều này: https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

tôi để lại thông tin này ở đây cho những người mà có thể có cùng một vấn đề.

Để làm cho nó rõ ràng hơn, những gì giúp là:

Tiêm ứng dụng trên một Singleton Háo hức và sau đó sử dụng classloader của nó để tải các lớp tôi đã gặp vấn đề với.

Để làm cho nó rõ ràng hơn

public class Module { 


@Override 
public void configure { 
    bind(TheClassLoaderLoader.class).asEagerSingleton() 

public static class TheClassLoaderLoader { 
    @Inject 
     public TheClassLoaderLoader(Application application) { 

     ClassLoader classloader = application.classloader(); 

       Class<?> interfaceClass = classloader.loadClass(InterfaceClass.class.getName()); 
       classloader.loadClass(ImplementsInterfaceClass.class.getName()).asSubclass(interfaceClass); 

Ví dụ dưới đây https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

Đó sử dụng Environment thường ném một bực bội ClassNotFoundException

Cheers

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