为什么Object [] .class.isAssignableFrom(String [] .class)== true?

时间:2009-10-30 16:36:01

标签: java arrays jvm

为什么Object[].class.isAssignableFrom(String[].class) == true,而String[].getSuperClass()getGenericInterfaces()无法获得Object[]

我检查了JDK的来源,但我认为我自己无法得到答案。 现在,我知道JDK使用树来存储Classes之间的关系,并使用深度来指示它的级别,Class::isAssignableFrom()搜索链,所以绝对数组在那个树中。并且String[]也与Object[]相关联。

我可以说String[]Object[]的子类吗? 或者它只是Java的另一个奇怪的东西?

4 个答案:

答案 0 :(得分:6)

Class.isAssignableFrom()基本上会检查subtyping relation。 “subtype”和“subclass”是两个不同的概念。类层次结构(即子类化)只是子类型的一部分。

Primitive typesarray types有特殊情况需要进行子类型分析。

数组类型的子类型规则是这样的(请注意,“> 1 ”表示“是一个直接的子类型”):

  
      
  • 如果ST都是参考类型,那么S[]&gt; 1 T[] iff S&gt; < sub> 1 T
  •   
  • Object&gt; 1 Object[]
  •   
  • Cloneable&gt; 1 Object[]
  •   
  • java.io.Serializable&gt; 1 Object[]
  •   
  • 如果p是基本类型,则:      
        
    • Object&gt; 1 p[]
    •   
    • Cloneable&gt; 1 p[]
    •   
    • java.io.Serializable&gt; 1 p[]
    •   
  •   

您的问题的重要部分是第一项:当且仅当组件类型X[]是子类型时,数组类型Y[]是数组类型X的子类型组件类型Y

另请注意,严格来说,Object[]String[]都不是类。它们是“唯一”类型。虽然每个类隐式都是一个类型,但事实并非如此。非类型的另一个示例是基本类型:booleanbytecharshortintlong,{ {1}}和float是类型,但它们不是类。

造成混淆的另一个原因是您可以轻松获取代表类型double个对象。再说一遍: not 意味着那些类型是类。

答案 1 :(得分:2)

在Java(和.NET)中,数组是协变的。这意味着您可以将Apple[]类型的实例传递给期望Fruit[]的方法,如果Apple继承Fruit。以下行有效:

Fruit[] fruits = apples; // apples is an Apple[]

这意味着可以从Fruit[]分配Apple[]

当然,这不是很安全。假设:

void someMethod(Object[] objects) {
    objects[0] = "Hello World"; // throws at run time.
}

void test() {
    Integer[] integers = new Integer[10];
    integers[0] = 42;
    someMethod(integers); // compiles fine.
}

当您想要使用数组内容(例如打印它)但不修改它时,此设计决策很方便。

答案 2 :(得分:0)

因为String[]实际上可以转换/扩展为Object[]

您可能会认为此测试是String[]可以从Object[]分配,but it actually测试相反(如果String[]可以分配 Object[])。

此代码按预期编译和执行:

public static void main(String[] args) {
    String[] strings = new String[]{ "hello", "world" };
    printArray(strings);
}

public static void printArray(Object[] array) {
    for (Object obj : array) {
        System.out.println(obj);
    }
}

答案 3 :(得分:0)

如果对象表示数组类,则返回表示Object类的Class对象。link