java 可变参数和泛型的返回类型

omhiaaxx  于 2023-02-18  发布在  Java
关注(0)|答案(1)|浏览(164)

我在Java中学习 varargs 如何处理泛型类型,当我试图返回泛型类型数组时,有一个函数,在本例中TString

static <T> T[] toArr(T... listObj){
    System.out.println("To arr");
    System.out.println(listObj.getClass().getName());
    System.out.println(listObj[0].getClass().getName());
    return listObj;
}

static <T> T[] getArr1(T a1, T a2){
    System.out.println("Get arr 1");
    System.out.println(a1.getClass().getName());
    return toArr(a1, a2);
}

public static void main(String[] args) {
    String[] res1 = getArr1("one", "two");
}

结果是

Get arr 1
java.lang.String
To arr
[Ljava.lang.Object;
java.lang.String
//Error: casting from [Ljava.lang.Object to [Ljava.lang.String

据我所知,当getArr1toArr传递2个String对象时,存储它们的数组被视为Object数组或T = Object,当接收到toArrObject[])的返回时,在getArr1处转换为String[]失败抛出异常。
当我用方法getArr2显式声明类型时,情况就不同了。

static String[] getArr2(String a1, String a2){
    System.out.println("Get arr 2");
    System.out.println(a1.getClass().getName());
    return toArr(a1, a2);
}

哪个输出到

Get arr 2
java.lang.String
To arr
[Ljava.lang.String;
java.lang.String

运行良好,没有任何错误。varargs 被视为String[]
我可以得到一些解释 varargs 是如何被不同地对待的相同的输入类型作为上述情况?

lyr7nygr

lyr7nygr1#

首先,varargs只是“在调用方法之前创建一个参数数组”的语法糖。也就是说,一个简单的varargs方法调用如下:

method("foo", "bar");

// ...

public static void method(String... params) { }

是句法糖:

String[] params = new String[] { "foo", "bar" };
method(params);

// ...

public static void method(String[] params) { }

第二,不允许you cannot create arrays of T(泛型类型参数). new T[]。这是因为T在运行时不存在。运行时不知道T是什么。另请参阅:Java generics type erasure: when and what happens?
那么,toArr的调用站点会发生什么呢?

return toArr(a1, a2);

这里a1a2都是T,但是我们不能这么做:

T[] params = new T[] { a1, a2 };
return toArr(params);

编译器只能在此处创建Object[]来存储参数:

Object[] params = new Object[] { a1, a2 };
return toArr(params);

另一方面,在getArr2中,a1a2String,所以编译器知道它可以创建一个String[]来存储它们。

相关问题