【问题标题】:Why Object[].class.isAssignableFrom(String[].class) == true?为什么 Object[].class.isAssignableFrom(String[].class) == true?
【发布时间】:2009-10-30 16:36:00
【问题描述】:

为什么是Object[].class.isAssignableFrom(String[].class) == true,而String[].getSuperClass()getGenericInterfaces()却得不到Object[]

我检查了JDK的来源,但我认为我自己无法得到答案。 目前,我知道 JDK 使用树来存储类之间的关系,并使用深度来指示其级别,Class::isAssignableFrom() 搜索了链,因此肯定数组在该树中。并且String[] 也连接到Object[]

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

【问题讨论】:

    标签: java arrays jvm


    【解决方案1】:

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

    Primitive typesarray types 有子类型的特殊情况。

    数组类型的子类型化规则是这样的(注意“>1”的意思是“是”的直接子类型):

    • 如果ST都是引用类型,那么S[] >1T[] iff S >1T.
    • Object >1Object[]
    • Cloneable >1Object[]
    • java.io.Serializable >1Object[]
    • 如果p 是原始类型,则:
      • Object >1p[]
      • Cloneable >1p[]
      • java.io.Serializable >1p[]

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

    还要注意,严格来说,Object[]String[] 都不是类。它们是“唯一”类型。虽然每个类都隐含地是一种类型,但反之则不然。不是类的类型的另一个示例是原始类型:booleanbytecharshortintlongfloatdouble 是类型,但它们是不是类。

    另一个造成混淆的原因是您可以轻松获得代表这些类型java.lang.Class 对象。再说一遍:这意味着这些类型是类。

    【讨论】:

    • 哇,你从哪里得到的规则?你能给我一个链接吗?似乎 String[] 是 Object[] 的子类。非常感谢
    • 不,String[] + 不是 Object[] 的子类+!这就是我一直在说的!这是一个+子类型+,但那是不同的东西!顺便说一句,我的答案中一直都有指向规则的链接。
    【解决方案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.
    }
    

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

    【讨论】:

    • 您显示的代码将在运行时抛出ArrayStoreException
    • ...或者根据基类型的对象进行修改,多态的目的。
    【解决方案3】:

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

    你可能会想,如果String[] 可以从Object[] 分配,but it actually 测试相反(如果String[] 可以分配 Object[])。 p>

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

    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);
        }
    }
    

    【讨论】:

      【解决方案4】:

      如果this对象代表一个数组类,则返回代表Object类的Class对象。link

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-20
        • 2010-10-26
        • 2018-11-03
        • 1970-01-01
        • 1970-01-01
        • 2011-02-14
        • 2021-09-23
        • 2018-10-29
        相关资源
        最近更新 更多