私が持っているとします:
class X
{
val listPrimitive: List[Int] = null
val listX: List[X] = null
}
Scala の各メソッドの戻り値の型を次のように出力します。
classOf[ComplexType].getMethods().foreach { m => println(s"${m.getName}: ${m.getGenericReturnType()}") }
listPrimitive: scala.collection.immutable.List<Object>
listX: scala.collection.immutable.List<X>
それで... listX の要素型が X であると判断できますが、listPrimitive の要素型が実際に java.lang.Integer であることをリフレクションによって判断する方法はありますか? ...
val list:List[Int] = List[Int](123);
val listErased:List[_] = list;
println(s"${listErased(0).getClass()}") // java.lang.Integer
注意。List の types パラメータを見つけることができるので、これは JVM タイプの消去による問題ではないようです。パラメータの型が java.lang.[numbers] である場合、scala コンパイラはこの型情報を破棄するようです。
アップデート:
次の実験により、このタイプの情報が利用可能であると思われます。次のように定義するとします。
class TestX{
def f(x:X):Unit = {
val floats:List[Float] = x.listPrimitive() // type mismatch error
}
}
X.class は jar 経由でインポートされます。このケースが正しくコンパイルに失敗するためには、完全な型情報が X.class で利用可能でなければなりません。
更新 2:
Java シリアライゼーション ライブラリの scala 拡張機能を作成していると想像してください。以下を実装する必要があります。
def getSerializer(clz:Class[_]):Serializer
次のいずれかに応じて、さまざまなことを行う必要がある関数:
clz==List[Int] (or equivalently: List[java.lang.Integer])
clz==List[Float] (or equivalently: List[java.lang.Float])
clz==List[MyClass]
私の問題は、私がこれまでにしか見ないことです:
clz==List[Object]
clz==List[Object]
clz==List[MyClass]
clz は clz.getMethods()(i).getGenericReturnType() としてこの関数に提供されるためです。
clz:Class[_] から始めて、失われた要素タイプ情報を回復するにはどうすればよいですか?
TypeToken が役立つかどうかはわかりません。その使用法は次のとおりです。
typeTag[T]
T を提供する必要があります (つまり、コンパイル時に)。
それで、解決策への 1 つのパス... いくつかの clz:Class[_] が与えられた場合、そのメソッドの戻り値の型の TypeToken を特定できますか? scala コンパイラがタイプの不一致エラーを正しく生成するには、この情報が .class ファイルに (どこかに) 含まれている必要があるため、明らかにこれが可能です (上記を参照)。