我想最好从我正在查看的行为开始:
public class genericTest {
public static void main(String[] args) {
String str = "5318008";
printClass(str); // class java.lang.String
callPrintClass(str); // class java.lang.String
printClassVarargs(str); // class java.lang.String
callPrintClassVarargs(str); // class java.lang.Object
}
public static <T> void printClass(T str) {
System.out.println(str.getClass());
}
public static <T> void printClassVarargs(T ... str) {
System.out.println(str.getClass().getComponentType());
}
public static <T> void callPrintClass(T str) {
printClass(str);
}
@SuppressWarnings("unchecked")
public static <T> void callPrintClassVarargs(T str) {
printClassVarargs(str);
}
}
看着printClass()
and callPrintClass()
,似乎一切正常。callPrintClass()
接受一个通用参数并传递它。printClass()
通过其正确的类型识别此变量,而不关心谁在发送参数,然后按预期执行并打印java.lang.String
.
但是当我们尝试使用可变参数时,这将停止工作。我希望printClassVarargs()
认识到它的参数是 type String[]
,就像没有 varargs 的方法识别其参数的类型一样。另请注意,如果我直接调用,则不会发生这种情况printClassVarargs()
(很高兴在那里输出String
),但只有当它被调用时callPrintClassVarargs()
,它才会忘记其参数的类型并假定它得到一个Object
. 我也意识到我必须在这里抑制编译器警告,这通常在我尝试转换泛型时出现,但我不确定那里到底发生了什么。
所以我的问题真的是两个。这种行为背后的原因是什么?这是类型擦除的某种结果,还是 Java 处理数组的方式?其次,有没有办法解决这个问题?
当然,这只是一个简单的例子。我不是试图以这种方式打印类名,而是最初在编写重载方法来连接数组时发现了问题。