Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的Varargs和泛型_Java_Generics_Variadic Functions - Fatal编程技术网

java中的Varargs和泛型

java中的Varargs和泛型,java,generics,variadic-functions,Java,Generics,Variadic Functions,考虑以下场景: <T> void function(T...args){ ...code... } void函数(T…args){ …代码。。。 } 然后我用一个整数[]来调用它。编译器如何假定T是整数,而不是整数[]?(请注意,我很高兴情况如此,但我仍然觉得这种模糊性很奇怪) 此外,如果我希望T为Integer[],是否还有其他方法可以这样做(假设装箱/取消装箱不存在)?泛型适用于对象引用,因此将适用于类的对象引用int[]是一个引用int数组的类,而int是一个基元In

考虑以下场景:

<T> void function(T...args){
   ...code...
}
void函数(T…args){
…代码。。。
}
然后我用一个
整数[]
来调用它。编译器如何假定
T
整数
,而不是
整数[]
?(请注意,我很高兴情况如此,但我仍然觉得这种模糊性很奇怪)


此外,如果我希望
T
Integer[]
,是否还有其他方法可以这样做(假设装箱/取消装箱不存在)?

泛型适用于对象引用,因此
将适用于类的对象引用
int[]
是一个引用
int
数组的类,而
int
是一个基元
Integer[]
是一个引用
Integer
数组的类,其中
Integer
是另一个类

在检查完这个之后,varargs参数
T。。。args
需要一个对象引用数组,因此
int[]
将是对象引用数组中的单个元素,而
Integer[]
是一个对象引用数组

如果要将
整数[]
作为varargs的每个元素发送,可以发送
整数[]
。我写了一个例子:

public class SomeMain {

    static <T> void foo(T...ts) {
        for(T t : ts) {
            System.out.println(t);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] ints = { 1, 2, 3 };
        Integer[] integers = { 1, 2, 3 };
        foo(ints);
        foo(integers);
        //note, here each element in the varags will behave as Integer[]
        foo(new Integer[][] { integers });
    }
}

泛型适用于对象引用,因此
将适用于类的对象引用
int[]
是一个引用
int
数组的类,而
int
是一个基元
Integer[]
是一个引用
Integer
数组的类,其中
Integer
是另一个类

在检查完这个之后,varargs参数
T。。。args
需要一个对象引用数组,因此
int[]
将是对象引用数组中的单个元素,而
Integer[]
是一个对象引用数组

如果要将
整数[]
作为varargs的每个元素发送,可以发送
整数[]
。我写了一个例子:

public class SomeMain {

    static <T> void foo(T...ts) {
        for(T t : ts) {
            System.out.println(t);
        }
        System.out.println();
    }

    public static void main(String[] args) {
        int[] ints = { 1, 2, 3 };
        Integer[] integers = { 1, 2, 3 };
        foo(ints);
        foo(integers);
        //note, here each element in the varags will behave as Integer[]
        foo(new Integer[][] { integers });
    }
}

寻找适用的方法分为三个阶段。在第一阶段,javac尝试精确匹配参数类型和方法参数类型。在这个阶段,方法的参数类型是
T[]
,参数类型是
Integer[]
,在
T
之后的两个匹配被推断为
Integer
,因此选择该方法作为适用的方法(没有其他重载方法需要考虑)。没有进行进一步的阶段

如果第一阶段没有产生适用的方法,javac将继续到其他阶段。例如,如果将
T
明确指定为
Integer[]
,则该方法在第一阶段将不匹配(因为
T[]
将不匹配
Integer[]

在第三阶段,考虑了varargs;javac将使用尾随参数类型匹配
T
,而不是
T[]


这确实非常令人困惑,而且对我们的直觉来说似乎是模棱两可的。

找到适用的方法有三个阶段。在第一阶段,javac尝试精确匹配参数类型和方法参数类型。在这个阶段,方法的参数类型是
T[]
,参数类型是
Integer[]
,在
T
之后的两个匹配被推断为
Integer
,因此选择该方法作为适用的方法(没有其他重载方法需要考虑)。没有进行进一步的阶段

如果第一阶段没有产生适用的方法,javac将继续到其他阶段。例如,如果将
T
明确指定为
Integer[]
,则该方法在第一阶段将不匹配(因为
T[]
将不匹配
Integer[]

在第三阶段,考虑了varargs;javac将使用尾随参数类型匹配
T
,而不是
T[]


这确实非常令人困惑,而且对我们的直觉来说似乎是模棱两可的。

Java编译器非常聪明,因为您给了它一个
Integer[]
,您的意思可能是
T
Integer
,而不是
Integer[]
。我假设这是Java语言规范的一部分,它将
定义为varargs

如果要指定
T
是什么,可以使用以下语法:

Integer[] ary = { 1, 2, 3 };
myObj.function(ary); // T is Integer
myObj.<Integer>function(ary); // T is Integer
myObj.<Integer[]>function(ary); // T is Integer[]


<Integer>function(ary); // this is invalid; instead you could do...
this.<Integer>function(ary); // this if it's an instance method
MyClass.<Integer>function(ary); // or this if it's static
Integer[]ari={1,2,3};
myObj.函数(ari);//T是整数
myObj.函数(ari);//T是整数
myObj.函数(ari);//T是整数[]
函数(ary);//这是无效的;相反,你可以。。。
此函数(ary);//如果它是一个实例方法,那么
MyClass.function(ary);//或者这个,如果它是静态的

Java编译器非常聪明,因为您给了它一个
整数[]
,所以您可能想让
T
成为
整数,而不是
整数[]
。我假设这是Java语言规范的一部分,它将
定义为varargs

如果要指定
T
是什么,可以使用以下语法:

Integer[] ary = { 1, 2, 3 };
myObj.function(ary); // T is Integer
myObj.<Integer>function(ary); // T is Integer
myObj.<Integer[]>function(ary); // T is Integer[]


<Integer>function(ary); // this is invalid; instead you could do...
this.<Integer>function(ary); // this if it's an instance method
MyClass.<Integer>function(ary); // or this if it's static
Integer[]ari={1,2,3};
myObj.函数(ari);//T是整数
myObj.函数(ari);//T是整数
myObj.函数(ari);//T是整数[]
函数(ary);//这是无效的;相反,你可以。。。
此函数(ary);//如果它是一个实例方法,那么
MyClass.function(ary);//或者这个,如果它是静态的

请注意,泛型与问题并不完全相关。如果函数签名是
void function(Object…args)
,则会出现完全相同的问题——如果传递类型为
Integer[]
的表达式,则可以将其解释为使用数组作为
args
,或作为
args
的元素之一

答案是,基本上,如果可能的话,编译器更愿意使用参数作为
args
。由于您传递的表达式具有“array of reference type”类型,因此它是兼容的
function((Object)myIntegerArray);