web-dev-qa-db-ja.com

実装されたインターフェースにキャストできません

私はとても混乱しています...

インターフェイスを直接実装するクラスがあります。

public class Device implements AutocompleteResult
{...}

ここに私が正しい変数を見ている証拠があります:

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

しかし、クラスのインスタンスをインターフェイスにキャストしようとすると、次のようになります。

AutocompleteResult result = (AutocompleteResult) match;

ClassCastExceptionが発生します。

ClassCastException: Device cannot be cast to AutocompleteResult

また、isAssignableFromはfalseを返し、理由はわかりません:

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

doc から:

クラスまたはこのClassオブジェクトによって表されるインターフェースがか、指定されたClassパラメーターによって表されるクラスまたはインターフェースと同じか、スーパークラスまたはスーパーインターフェースです

クラスが実装するインターフェースにオブジェクトを常にキャストできるとは限りませんか?

ありがとう。

40
pstanton

これは、2つの異なるクラスローダーがAutocompleteResultという名前のクラスをロードした場合に発生する可能性があります。

これらの2つのクラスは、同じパッケージと名前(および実装/フィールド/メソッド)であっても、まったく異なるクラスとして扱われます。

これの一般的な原因は、ある種のプラグインシステムと、ベースクラスとプラグインクラスprovideの両方を同じクラスで使用している場合です。

この問題をチェックするには、 Class.getClassLoader() によって返された値を両方の問題のあるクラス(つまり、DeviceおよびAutocompleteResult.class)の結果。

66
Joachim Sauer

AKA Javaの場合、Javaではないようです。

私は最近Play Framework 2.6.3でこの問題に遭遇しました、私を助けたのはこれでした: https://www.playframework.com/documentation/2.6.x/ThreadPools#Application-class-loader

同じ問題を抱えている可能性のある人のために、ここにこの情報を残します。

より明確にするために、役立つのは:

イーガーシングルトンにアプリケーションを注入し、そのクラスローダーを使用して、問題があったクラスをロードします。

より明確にするために

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

ここの例 https://playframework.com/documentation/2.6.x/JavaDependencyInjection#Configurable-bindings

Environmentを使用すると、イライラするClassNotFoundExceptionが頻繁にスローされます

乾杯

0
João Antunes