编写代码时常会碰到一些错误,包括编译时异常和运行时异常,对于初学者来说,编译异常按照开发工具提示可以自动进行处理,但是对于运行时异常需要一些经验判断来进行处理,先将一些常见的运行时异常错误进行汇总。
1. 空指针异常(NullPointerException)
当访问一个空引用对象的属性或调用空引用对象的方法时,会抛出空指针异常NullPointerException。示例代码如下:
String str = null;
System.out.println(str.length());
此时str没有指向任何地址,调用方法length()时报空指针异常NullPointerException,为避免此错误出现,调用前先判断不为空,示例代码如下所示:
String str = null;
if(str!=null){
System.out.println(str.length());
}
2. 数组越界异常(ArrayIndexOutOfBoundsException)
当访问数组时,下标有效范围是0~数组长度-1,超出有效索引范围的位置时,会抛出数组下标越界异常ArrayIndexOutOfBoundsException。示例代码如下:
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
数组arr下标从0开始,最大下标是2,此时arr[3]访问下标为3的元素,数组下标不存在报数组下标越界异常ArrayIndexOutOfBoundsException。为避免此错误出现,下标应满足0~arr.length-1。
3. 除零异常(ArithmeticException)
当进行整数除法或取模运算时,除数为零会抛出除零异常ArithmeticException。示例代码如下:
int a = 5;
int b = 0;
System.out.println(a/b);
除数b为0,会报除零异常ArithmeticException。为避免此错误出现,在进行除法或取模运算时,要确保除数不为零,可以使用条件语句预先检查除数是否为零。示例代码如下:
int a = 5;
int b = 0;
if(b!=0){
System.out.println(a/b);
}
4. 类型转换异常(ClassCastException)
当父引用指向一个子类对象,强制将父引用转换成另一个子类对象时,会抛出类型转换异常ClassCastException。示例代码如下:
Person p = new Teacher();
Student stu = (Student)p;
当Person类父引用对象p指向子类Teacher对象时,强制将父引用对象p转换成另一个子类Student,报类型转换异常ClassCastException。为避免此错误出现,在强制类型转换前,先做判断父引用是否是此类型。示例代码如下:
Person p = new Teacher();
if(p instanceof Student){
Student stu = (Student)p;
}
5. 并发修改异常(ConcurrentModificationException)
当在进行迭代或增强for循环操作时,试图并发修改集合(如ArrayList)的结构时,会抛出并发修改异常ConcurrentModificationException。示例代码如下:
List<String> list = new ArrayList<>();
list.add("Java");
for (String item : list) {
if (item.equals("Java")) {
list.remove(item);
}
}
使用增强for循环时,在循环体中remove()删除集合list中元素,报并发修改异常ConcurrentModificationException。为避免此错误出现,在迭代时修改集合的结构。可以使用Iterator进行迭代,并使用Iterator的remove()方法删除元素,示例代码如下:
List<String> list = new ArrayList<>();
list.add("Java");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (item.equals("Java")) {
iterator.remove();
}
}
6. 栈溢出错误(StackOverflowError)
当方法调用的嵌套层级过深,导致栈空间耗尽时,会抛出栈溢出错误StackOverflowError。示例代码如下:
public static void recursiveMethod() {
recursiveMethod();
}
public static void main(String[] args) {
recursiveMethod();
}
此递归调用没有返回值,会无限次递归下去,报栈溢出错误StackOverflowError。为避免此错误出现,确保递归方法具有退出条件,避免无限递归调用。每次递归调用时,问题规模应该减小,直到达到退出条件。示例代码如下:
public static void recursiveMethod(int n) {
if (n <= 0) {
return;
}
// 进行递归操作
recursiveMethod(n - 1);
}
7. 数字格式化异常(NumberFormatException)
当尝试将一个无法转换为数字的字符串转换为数字类型时,会抛出数字格式化异常NumberFormatException。示例代码如下:
String str = "ABC123";
int number = Integer.parseInt(str);
将字母转换成数字时,报数字格式化异常NumberFormatException。为避免此错误出现,在进行字符串转换为数字的操作之前,确保字符串仅包含有效的数字字符。可以使用正则表达式或合适的校验方法来验证字符串是否为有效的数字。示例代码如下:
String str = "ABC123";
if(str.matches(“\\d+”)){
int number = Integer.parseInt(str);
}
8. 无此元素异常(NoSuchElementException)
当使用迭代器循环时,在循环题代码中,如果不止一次调用next()方法时,可能会报无此元素异常(NoSuchElementException)。示例代码如下:
Map<String,Integer> map= new HashMap<String,Integer>();
map.put(“Jim”,100);
Set<String> keySet =map.keySet();
Iterator<String> it = keySet.iterator();
while (it.hasNext()) {
String key = it.next();
Integer value = map.get(it.next());
}
此时迭代器循环中,it.next()方法执行两次,报无此元素异常(NoSuchElementException)。为避免此错误出现,在迭代器循环体中,只使用一次it.next()方法,取出存储到变量中,使用变量。示例代码如下:
Map<String,Integer> map= new HashMap<String,Integer>();
map.put(“Jim”,100);
Set<String> keySet =map.keySet();
Iterator<String> it = keySet.iterator();
while (it.hasNext()) {
String key = it.next();
Integer value = map.get(key);
}
上述错误是Java中常见的运行时异常,初学者在写此类代码时多多注意,避免出错。
Copyright © 2004-2024 华清远见教育科技集团 版权所有
京ICP备16055225号-5,京公海网安备11010802025203号