Open
Description
reproduction steps
using Scala 2.13.4,
class Poly[A](val value: A) extends AnyVal
class Arr[A](val value: Array[A]) extends AnyVal
class ArrRef[A <: AnyRef](val value: Array[A]) extends AnyVal
class Test {
def poly1(x: Poly[Int]): Poly[Int] =
new Poly(x.value)
def poly2(x: Poly[String]): Poly[String] = // correct signature
new Poly(x.value)
def poly3(x: Poly[Array[Int]]): Poly[Array[Int]] = // correct signature
new Poly(x.value)
def poly4(x: Poly[Array[String]]): Poly[Array[String]] = // correct signature
new Poly(x.value)
def arr1(x: Arr[Int]): Arr[Int] =
new Arr(x.value)
def arr2(x: Arr[String]): Arr[String] =
new Arr(x.value)
def arr3(x: Arr[Array[Int]]): Arr[Array[Int]] =
new Arr(x.value)
def arr4(x: Arr[Array[String]]): Arr[Array[String]] =
new Arr(x.value)
def arrRef1(x: ArrRef[Integer]): ArrRef[Integer] =
new ArrRef(x.value)
def arrRef2(x: ArrRef[String]): ArrRef[String] =
new ArrRef(x.value)
def arrRef3(x: ArrRef[Array[Int]]): ArrRef[Array[Int]] =
new ArrRef(x.value)
def arrRef4(x: ArrRef[Array[String]]): ArrRef[Array[String]] =
new ArrRef(x.value)
}
problem
When using javap
we can observe that the generic signature of these methods (the one that javap displays first and that comes from the Signature
attribute) does not match their descriptor (which is the actual signature the JVM cares about); except for the ones I marked // correct signature
:
% javap -p -v Test|grep -B1 descriptor
...
--
public int poly1(int);
descriptor: (Ljava/lang/Integer;)Ljava/lang/Integer;
--
public java.lang.String poly2(java.lang.String);
descriptor: (Ljava/lang/String;)Ljava/lang/String;
--
public int[] poly3(int[]);
descriptor: ([I)[I
--
public java.lang.String[] poly4(java.lang.String[]);
descriptor: ([Ljava/lang/String;)[Ljava/lang/String;
--
public int[] arr1(int[]);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
--
public java.lang.String[] arr2(java.lang.String[]);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
--
public int[][] arr3(int[][]);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
--
public java.lang.String[][] arr4(java.lang.String[][]);
descriptor: (Ljava/lang/Object;)Ljava/lang/Object;
--
public java.lang.Integer[] arrRef1(java.lang.Integer[]);
descriptor: ([Ljava/lang/Object;)[Ljava/lang/Object;
--
public java.lang.String[] arrRef2(java.lang.String[]);
descriptor: ([Ljava/lang/Object;)[Ljava/lang/Object;
--
public int[][] arrRef3(int[][]);
descriptor: ([Ljava/lang/Object;)[Ljava/lang/Object;
--
public java.lang.String[][] arrRef4(java.lang.String[][]);
descriptor: ([Ljava/lang/Object;)[Ljava/lang/Object;
--
...
This can only end in disaster when Java tries to call these methods:
public class J {
public static void main(String[] args) {
Test test = new Test();
test.poly1(1);
}
}
% javac J.java
% java J
Exception in thread "main" java.lang.NoSuchMethodError: Test.poly1(I)I
at J.main(J.java:4)