有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Varags对象处理异常

我不明白varargs是如何处理传入的对象的:

public class NoSense {

public static void someMethod(String a, Object... things) {

    System.err.println("a->" + a);

    System.err.println(things.getClass().getName());

    for (Object object : things) {
        System.err.println("thing->" + object);
    }


}


public static void main(String[] args) {
    String[] x = new String[] { "what", "is", "up?" };
    NoSense.someMethod("1", x);
    NoSense.someMethod("2", x, "extra");
}

}

结果是

a->1
[Ljava.lang.String;
thing->what
thing->is
thing->up?
a->2
[Ljava.lang.Object;
thing->[Ljava.lang.String;@4d20a47e
thing->extra

为什么它会将第一个集合视为字符串数组,将第二个集合视为对象数组引用


共 (2) 个答案

  1. # 1 楼答案

    因为第一个参数之后的所有参数都被认为是要存储在varargs数组中的值。但是,Java将只传递数组的情况视为特殊情况,并将其作为varargs值

    案例1: 只有一个值被传递给对象[]的varargs。此值为字符串[]。Java将其视为特例,并直接传递数组

    案例2: 将两个值传递给对象[]的varargs。第一个值的类型为String[],第二个值的类型为String。由于传递的值不止一个,因此这不是特例。因此,vargargs参数是一个对象[](正如您定义的那样),第一个元素是传递的字符串数组,第二个元素是字符串

  2. # 2 楼答案

    因为String[]引用通过数组协方差隐式转换为Object[]。编译器不需要使用varargs,所以它不需要

    要强制使用varargs,我们只需将其转换为^{

        NoSense.someMethod("1", (Object) x);
    

    现在Object不能隐式转换为Object[],因此编译器将它包装在一个数组中

    根据JLS第15.12.4.2节:

    If m is being invoked with k != n actual argument expressions, or, if m is being invoked with k == n actual argument expressions and the type of the kth argument expression is not assignment compatible with T[], then the argument list (e1, ... , en-1, en, ...ek) is evaluated as if it were written as (e1, ..., en-1, new T[]{en, ..., ek}).