【发布时间】:2013-12-09 02:04:17
【问题描述】:
刚看了《Effective Java》,看到一句话是这么说的
因此,数组提供运行时类型安全,但不提供编译时类型安全,泛型反之亦然
我不太清楚,即使在阅读了所有给出的示例后我也很困惑。谁能给我解释一下,谢谢一百万。
【问题讨论】:
刚看了《Effective Java》,看到一句话是这么说的
因此,数组提供运行时类型安全,但不提供编译时类型安全,泛型反之亦然
我不太清楚,即使在阅读了所有给出的示例后我也很困惑。谁能给我解释一下,谢谢一百万。
【问题讨论】:
您不能在运行时更改数组(引用)的类型。但是你可以编译尝试的代码就可以了。
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
换句话说,您不需要实际运行您的应用程序并执行该部分代码来查找问题。
请注意,编译时故障比运行时故障更可取,因为您在将问题发布给用户之前就发现了问题(之后为时已晚)!
【讨论】:
对于泛型集合,此代码尝试将整数放入字符串列表,在第二行给出编译时错误: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;
但是,如果它实际上包含整数,它就不是一个有效的字符串数组,因此在运行时会检查每个在其中存储内容的操作。在运行时它会以ArrayStoreException 爆炸。
【讨论】:
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 {
}
【讨论】: