Java では、ジェネリックでプリミティブ型がサポートされていないため、これが問題になることはありません。したがって、次のコードは Java ではかなり合法です。
public static <T> void f(T t){out.println("normal type");}
public static <T> void f(T[] a){out.println("Array type");}
一方、Scala はすべての型のジェネリックをサポートしています。Scala 言語にはプリミティブがありませんが、結果のバイトコードでは Int、Float、Char、Boolean などの型にプリミティブが使用されます。これが Java コードと Scala コードの違いになります。は .ではないint[]
ため、Java コードは配列として受け入れません。したがって、Java はこれらのメソッド パラメータ タイプをおよびに消去できます。(つまり、JVM 上で。)int
java.lang.Object
Object
Object[]
Ljava/lang/Object;
[Ljava/lang/Object;
一方、Scala コードは 、 、 などを含むすべての配列をArray[Int]
処理Array[Float]
しArray[Char]
ますArray[Boolean]
。これらの配列は、プリミティブ型の配列です (またはその可能性があります)。Array[Object]
JVM レベルまたはJVM レベルでキャストすることはできませんArray[anything else]
。Array[Int]
andのスーパータイプは 1 つだけです。Array[Char]
それはjava.lang.Object
です。これは、より一般的なスーパータイプです。
これらのステートメントをサポートするために、一般的でないメソッド f を使用してコードを作成しました。
def f[T](t: T) = println("normal type")
def f[T <: AnyRef](a: Array[T]) = println("Array type")
このバリアントは、Java コードのように機能します。つまり、プリミティブの配列はサポートされていません。しかし、この小さな変更は、コンパイルするには十分です。一方、次のコードは型消去の理由でコンパイルできません。
def f[T](t: T) = println("normal type")
def f[T <: AnyVal](a: Array[T]) = println("Array type")
ジェネリック メソッドが生成されるため、@specialized を追加しても問題は解決しません。
def f[T](t: T) = println("normal type")
def f[@specialized T <: AnyVal](a: Array[T]) = println("Array type")
@specialized が問題を解決したことを願っていますが (場合によっては)、コンパイラは現時点ではサポートしていません。しかし、それが scalac の優先度の高い拡張になるとは思いません。