2

クラスを引数として受け取る、使用する必要があるレガシー ライブラリに Java メソッドがあるとします。

public void takeClass(Class<? extends JavaClass> cls);

ここで、JavaClass を拡張する Ceylon クラスがあるとします。

shared class CeylonClass() extends JavaClass() {}

takeClassさて、これが機能するようにセイロンでメソッドを使用するにはどうすればよいですか?

javaThing.takeClass( `class CeylonClass` );

// or maybe this should work?
javaThing.takeClass( javaClass<CeylonClass>() );

上記のように、javaClassモジュール内で機能を試してみましたがceylon.interop.java成功しませんでした...javaClass<JavaClass>()そうすると動作しますが、もちろんこれは私には役に立ちません。

編集:

上記のように使用すると発生するエラーjavaClass<CeylonClass>()

argument must be assignable to parameter class of takeClass:
Class<CeylonClass> is not assignable to Class<JavaClass>?
4

1 に答える 1

2

残念ながら、これは Java に戻って接着剤を追加する必要がある場合です。今日、セイロンで完全に書くことはできません。

説明

問題は、Ceylon には use-site 共分散がなく、Ceylon タイプチェッカーはJavaの use-site 共分散さえ理解しないため、タイプチェッカーは次のメソッドを処理することです。

public void takeClass(Class<? extends JavaClass> cls);

このより制限的な署名があるかのように:

public void takeClass(Class<JavaClass> cls);

さらに、タイプチェッカーは、すべての Java クラスを不変の型であるかのように扱います。

したがって、 はjavaClass<CeylonClass>()を生成するためClass<CeylonClass>、 のパラメータに割り当て可能とは見なされませんtakeClass()。:-(

回避策

回避策は、次の Java メソッドを追加することです。

public static <T extends JavaClass> void takeClass2(Class<T> cls) {
    takeClass(cls);
}

このメソッドは、Ceylon から次のように呼び出すことができます。

javaThing.takeClass2( javaClass<CeylonClass>() );

HTH

PS

これを書いているうちに、実はjava.lang.Class共変型であることに気付きました.Ceylonもそれを簡単に認識できるはずだと思います. だから私はこの問題を作成しました:

https://github.com/ceylon/ceylon-compiler/issues/1474

于 2013-11-28T03:49:18.367 に答える