如何确定 varargs 数组的组件类型?

2022-09-03 15:46:51

使用 varargs 时,如何确定结果数组的组件类型?

例如,此程序是否保证打印,或者其行为在技术上是否未指定?true

public static void main(String[] args) {
    foo("", 0);
}

static <T> void foo(T... arr) {
    System.out.println(arr.getClass() == Serializable[].class);
} 

答案 1

我运行了这段代码,输出告诉你没有保证(至少如果类在不同的层次结构分支上有多个共同的祖先)

老实说,我不知道这种魔力背后的原因,但我只是不能将其作为评论发布

import java.util.*;
import java.lang.*;
import java.io.*;

class Ideone
{

  interface A{}
  interface B{}
  class AB implements A, B {}
  class BA implements A, B {}

    public static void main (String[] args) throws java.lang.Exception
    {
        foo(new AB(), new BA());
        foo2(new AB(), new BA());
    }

    static <T> void foo(T... arr) {
        System.out.println(arr.getClass() == A[].class);
    }

    static <T> void foo2(T... arr) {
        System.out.println(arr.getClass() == B[].class);
    } 
}

输出

true
false

更多奇怪的事情:

如果在 之前声明 ,则结果与结果相反:interface Binterface A

false
true

更改方法调用中的参数顺序,方法声明顺序和块中接口的顺序对我不起作用(1.8.0_51)。implements


答案 2

这个答案可能不是100%你正在寻找的答案,但也许它会有所帮助。一般来说,arr.getClass() 会返回一些数组类(最通用的 ,但也可以是 、 , 甚至 - 通常是所有元素中最具体的类型,但我不会指望它看到 m-szalik 答案)。如果要确保数组中包含的所有类都是的实例,则必须检查每个元素(顺便说一句,所呈现的实现不支持值):Object[].classInteger[].classNumber[].classSerializable[].classSerializablenull

static <T> void foo(T... arr) {
    System.out.println(Stream.of(arr)
            .filter(e -> !Serializable.class.isInstance(e.getClass()))
            .findFirst()
            .orElse(null) == null);
}

您可能想看看:

顺便说一句。我同意福盖蒂船长的观点:

好吧,我不是100%确定这一点,但我认为这与varargs无关,而更像是动态绑定,泛型和类型擦除。

注意

下面是一些实现示例:foo

  • foo(1, 2)Integer[].class
  • foo(1, 2.0)Number[].class
  • foo ("", 1)Serializable[].class
  • foo(null, 2)Integer[].class
  • foo("", new Object())Object[].class