将运行时错误改为编译时错误
运行时错误和编译时错误是什么?
- 运行时错误指的是在运行后才会报错的问题,如除0、溢出
- 编译时错误指的是在代码中即可提示的问题,若非法参数、非法赋值
例1
如下对一个数组进行冒泡排序
public static Object[] sort(Object[] objects) {
for (int i = 0; i < objects.length - 1; i++) {
for (int j = i + 1; j < objects.length - 1 - i; j++) {
if (((Comparable) objects[i]).compareTo(objects[j]) > 0) {
Object temp = objects[i];
objects[i] = objects[j];
objects[j] = temp;
}
}
}
return objects;
}
但以上方法可能发生运行时错误(类型转换出错),而将Object改为Comparable,可转为编译时错误
public static Comparable[] sort(Comparable[] compares) {
for (int i = 0; i < compares.length - 1; i++) {
for (int j = i + 1; j < compares.length - 1 - i; j++) {
if (compares[i].compareTo(compares[j]) > 0) {
Comparable temp = compares[i];
compares[i] = compares[j];
compares[j] = temp;
}
}
}
return compares;
}
例2
如下是从集合中随机获取一个元素,采用Object[ ]数组存储
class Choose {
private final Object[] array;
public Choose(Collection collection) {
array = collection.toArray();
}
public Object random() {
Random random = ThreadLocalRandom.current();
return array[random.nextInt(array.length)];
}
}
对于每次调用random(),都需要手动对Object进行类型转换,如果搞错就会报运行时错误
List<String> strings = new ArrayList<>();
strings.add("song");
Choose choose = new Choose(strings);
String s = (String) choose.random();
将Choose其改为泛型,并将collection.toArray()返回的Object[]转为T[]
class Choose<T> {
private final T[] array;
public Choose(Collection<T> collection) {
array = (T[]) collection.toArray();
}
public T random() {
Random random = ThreadLocalRandom.current();
return array[random.nextInt(array.length)];
}
}
在调用时可指定泛型类型以省去对类型的转换
List<String> strings = new ArrayList<>();
strings.add("song");
Choose<String> choose = new Choose<>(strings);
String s = choose.random();
因为不知道T的具体类型,编译器无法检查Object[ ]是否可以转为T[ ],所以会给出Unchecked异常,如果确保代码无问题,可添加@SuppressWarnings(“unchecked”)消除它
但更好的做法是使用List代替数组T[ ],这样既不会出现类型转换异常,又不会出现Unchecked异常,但是运行速度可能会稍慢一点,如下
class Choose<T> {
private final List<T> array;
public Choose(Collection<T> collection) {
array = new ArrayList<>(collection);
}
public T random() {
Random random = ThreadLocalRandom.current();
return array.get(random.nextInt(array.size()));
}
}