Java入门常见异常
前言:简单整理了一些Java入门时常见的异常
一、运行时异常
1.数组索引越界异常
int [] arr=new int [3]; //定义一个数组,数组长度为3,索引为0,1,2
System.out.println(arr[3]); //输出arr[3]
/*
结果:
ArrayIndexOutOfBoundsException:数组索引越界异常
原因分析:
arr[3]的索引超出了数组arr的索引范围
*/
2.空指针异常
int [] arr=new int[3]; //定义一个数组,数组长度为3
System.out.println(arr); //输出的是arr的地址值
System.out.println(arr[2]) //输出arr[2]的值,初始化值为0
arr=null; //arr的地址值指向null
System.out.println(arr[2]); //再次输出arr[2]的值
/*
结果:
NullPointerException:空指针异常
原因分析:
数组是引用数据类型,是通过地址值进行存储和访问的。
数组arr的地址值指向null,无法访问到arr[2],显示异常
*/
3.算术异常
System.out.println(1/0); //输出1/0; 补充:/取商,%取余
/*
结果:
ArithmeticException:算术异常
原因分析:
0作为了除数,1/0,没有意义
*/
4.内存溢出
int [] arr=new int[999999999]; //定义一个数组,长度为999999999
/*
结果:
OutOfMemoryError:内存溢出
原因分析:
超出Java Heap Space(Java堆内存) //补充:Error,计算机硬件不足时才会出现Error,错误
*/
5.类转换异常
public abstract class Animal {}
public class Cat extends Animal {}
public class Dog extends Animal {}
public class AnimalDemo{
public static void main(String[] args){
Animal a1=new Cat();
Animal a2=new Dog();
Cat cat1 = (Cat)a1 ;
Cat cat2 = (Cat)a2 ;
}
}
/*
代码块功能:
1.定义了一个抽象类Animal,定义了一个Cat类继承Animal类,定义了一个Dog类继承Animal类
2.在测试类中以多态的形式创建对象a1和a2(向上转型)
3.a1和a2向下转型,强转
*/
/*
结果:
第四行代码 Cat cat2 = (Cat)a2 报错 ClassCastException 类转换异常
原因分析:
向下转型,可能转型错误,
代码中将a2(Dog类)转换为Cat类,强转失败
简明地说,猫是动物,狗也是动物,可以进行转换,但猫不是狗,狗也不是猫,不能进行互相转换
解决方案:
先进行类型判断,
if(a2 instanceof Cat) {
Cat cat2 = (Cat) a2;
}
以上代码用了instanceof,判断a2是否是Cat类,如果a2是Cat类,那么就可以进行转换,否则不能进行转换
*/
6.被请求的元素不存在
Collection<String> c=new ArrayList<>();
c.add("I");
c.add("Love");
c.add("u");
Iterator<String> it=c.iterator();
System.out.println(it.next());//输出"I"
System.out.println(it.next());//输出"Love"
System.out.println(it.next());//输出"u"
System.out.println(it.next());//报错
/*
代码块功能:
1.创建一个新的Collection集合对象c
2.将字符串"I","Love","u"添加到集合中
3.用迭代器遍历集合并输出
*/
/*
结果:
NoSuchElementException 被请求的元素不存在异常
原因分析:
因为Collection中只有"I","Love","u"三个元素,当第四次调用next()方法时,已经没有下一个元素,即被请求的元素不存在,所以报错
解决方案:
先判断是否有下一个元素,再调用next()方法;
Iterator<String> it=c.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
*/
7.并发修改异常
List<String> list=new ArrayList<>();
list.add("I");
list.add("Love");
list.add("u");
Iterator<String> it=list.iterator();
while(it.hasNext()){
String s=it.next();
if(s.equals("Love")){
list.add("not"); //报错
}
}
/*
代码块功能:
1.创建一个新的Collection集合对象c
2.将字符串"I","Love","u"添加到集合中
3.调用迭代器方法,对字符串逐个进行判断,当字符串为"Love"的时候,将字符串"not"添加到集合中
*/
/*
结果:
第九行代码list.add("not")报错,ConcurrentModificationException
在使用了【迭代器】进行集合遍历的时候(确切的说,在调用了【迭代器】之后),对集合进行【添加】或者【删除】的时候,会出现并发修改异常
原因分析:
在创建集合的时候,会定义一个值,modCount(实际修改集合的次数),初始值为0
每次【添加】或者【删除】集合元素的时候,modCount都会++,
在调用了【迭代器】以后,也会定义一个值,expectedModCount(预期修改集合的次数),并将modCount的值赋值给expectedModCount
随后在调用迭代器方法的时候,会判断expectedModCount和modCount是否相等
如果进行了【添加】或者【删除】操作的话,modCount会++,但是expectedModCount的值不变,,判断结果就不相等,就会出现并发修改异常ConcurrentModificationException
解决方案:
1.使用for循环,用get方法获得每个元素
2.使用List独有【迭代器】ListIterator进行遍历操作
*/
二、编译时异常
1.解析异常
public static void main(String[] args){
Date d = new Date();
String s1="2020-12-3 13:14:00";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d1 = sdf.parse(s1); //编译不通过
System.out.println(d1);
}
/*
代码块功能:
1.创建了Date类对象d
2.定义字符串,s1="2020-12-3 13:14:00"
3.创建了SimpleDateFormat类对象sdf
4.调用SimpleDateFormat的parse()方法,将s1作为参数传入,返回日期格式d1
5.输出d1
*/
/*
结果:
第4行代码,Date d1 = sdf.parse(s1),编译不通过
parse下划线显示unhandled exception:java.text.ParseException
原因分析:
SimpleDateFormat调用parse方法将字符串按照一定格式转换成日期形式。
设定的格式可能与想要解析的字符串不匹配,可能会出错导致ParseException(可能会出错)
解决方案:
需要在方法的括号后面抛出异常
public static void main(String[] args) throws ParseException{}
*/
结语:简单整理,希望对进来的小伙伴们有帮助哈!