【问题标题】:Java Array declaration like { A[] aa = new B[10]}Java 数组声明,如 { A[] aa = new B[10]}
【发布时间】:2011-12-13 18:41:27
【问题描述】:

今天我写了一个关于声明数组语法的简单测试,所以,有3个类:

public class A {
}

public class B extends A {
}

public class C extends A {
}

我尝试使用下一个语法创建数组

A[] aa = new B[10];

所以,这是可能的,但我们可以只将 B 类的实例添加到此数组中,如果您尝试添加 AC 的实例,您会收到 java.lang.ArrayStoreException 和问题,为什么我们可以使用这样的语法创建数组,它在哪里可以使用并获得一些利润? 谢谢。

【问题讨论】:

    标签: java arrays syntax


    【解决方案1】:

    该数组包含 Bs 类型。尽管引用 aa 可以保存 A[]、B[] 或 C[] 类型的数组(因为 C 和 B 都扩展 A),但在运行时,该数组只能保存 Bs。

    A 类不是 B。C 类不是 B。因此运行时异常。

    编辑:

    这样的代码有很多潜在用途。例如,您可以像这样声明一个数组,因为您可能直到运行时才知道您正在使用的更明确的类型。

    例如:

    Animal[] animals;
    if (useDogs) {
     animals = new Dog[num];
    } else {
     animals = new Cat[num];
    }
    
    loadIntoCar(animals);
    

    【讨论】:

    • 我的问题的答案在哪里,我完全理解发生了什么,但为什么我们可以这样声明数组?
    • 我考虑过这种情况,但认为这是架构中的问题,我是关于您的编辑
    【解决方案2】:

    语言中允许使用这种语法的原因是,有时您并不关心数组中对象的子类。用于数组子类型化的Java Language Specification rules 包括:

    如果 ST 都是引用类型,则 S[] >1T [] 当且仅当 S >1T.

    (其中 >1 表示“直接子类型”)。

    这允许人们编写这样的方法:

    public void printArray(Object[] array) {
        System.out.print('[');
        boolean first = true;
        for (Object obj : array) {
            if (!first) {
                System.out.print(", ");
            } else {
                first = false;
            }
            System.out.print(String.valueOf(obj));
        }
        System.out.print(']');
    }
    

    然后调用它:

    String[] foo = { "a", "b", "c" };
    printArray(foo);
    

    这个语言特性确实具有将 ArrayStoreException 问题推迟到运行时的不幸效果。

    【讨论】:

    • 谢谢,是的,这只是我发明的一种使用方式。
    【解决方案3】:

    数组类型是covariant,这意味着你可以声明 A[] a = new B[] (集合,相反,不是:你不能声明 List a = new List() )。

    这就是为什么编译器无法预先检查您是否只会将有效类型的元素放入数组中,这解释了为什么检查只发生在运行时,当您尝试将元素插入数组时。

    【讨论】:

      【解决方案4】:

      如果您需要示例,请查看Arrays。如果 Java 不允许数组多态,我们就不能有 sort(Object[] a)toString(Object[] a)binarySearch(Object[] a, Object key) 等功能。请记住 BCObject 的子类型,所以你可以为所有人使用该功能。请注意,数组早于泛型(Java 1.5.0),甚至泛型也存在缺陷(Java 的权衡是由于类型擦除,您无法在运行时知道泛型类型)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-04-11
        • 1970-01-01
        • 2021-07-15
        • 1970-01-01
        • 2017-01-21
        • 1970-01-01
        • 2022-11-16
        相关资源
        最近更新 更多