数组和泛型之间有所不同

时间:2013-12-09 02:04:17

标签: java arrays generics

我刚读过“Effective Java”,我看到一句话说

因此,数组提供运行时类型安全性,但不提供编译时类型安全性,反之亦然

我对此并不十分清楚,即使在我阅读了所有给出的例子之后我也很困惑。任何人都可以向我解释这一点,感谢一百万。

3 个答案:

答案 0 :(得分:3)

您无法在运行时更改数组(引用)的类型。但是你可以编译尝试的代码。

String[] strings = new String[1];
Object[] objects = strings;
objects[0] = new Integer(1); // RUN-TIME FAILURE

当您编译您的应用程序时,编译器不会抛出任何错误。

另一方面,如果你使用泛型,那么当你编译(构建)你的应用程序时,这会给你一个错误。

ArrayList<String> a = new ArrayList<String>();
a.add(5); //Adding an integer to a String ArrayList - compile-time failure

换句话说,您不需要实际运行应用程序并执行该部分代码来查找问题。

请注意,编译时故障比运行时故障更可取,因为您在将问题发布给用户之前就已发现问题(之后为时已晚)!

答案 1 :(得分:0)

对于泛型集合,此代码尝试将Integer放入String列表中,在第二行给出编译时错误:Cannot cast from List<String> to List<Object>

List<String> listOfStrings = new ArrayList<>();
List<Object> listAgain = (List<Object>)listOfStrings;
listAgain.add(123);

与数组的等效代码编译完美,因为将String数组用作Object数组是合法的。 (从技术上讲,数组是covariant。)

String[] arrayOfStrings = new String[10];
Object[] arrayAgain = arrayOfStrings;
arrayAgain[0] = 123;

但是,如果它实际上包含整数,它将不是一个有效的String数组,因此在运行时检查每个存储内容的操作。在运行时,它会以ArrayStoreException爆炸。

答案 2 :(得分:0)

Java Array提供协变返回类型,而泛型不提供协变返回类型。
 
让我们用简单的例子来理解

public class GenericArrayDiff {
    public static void main(String[] args) {
        List<Vehicle> vehicleList = null;
        List<Car> carList =  null;
        Vehicle[] vehicleArrays;
        Car[] carArrays;

        // illegal
        carList = vehicleList;
        // illegal
        vehicleList = carList;
        // illegal
        carArrays = vehicleArrays;
        // legal because array provides covariant return type
        vehicleArrays = carArrays;
    }

}
class Vehicle {

}
class Car extends Vehicle {

}