异常
Throwable
Error
定义:
不应被程序捕获的严重问题,无需throws
(出现了就应该停下程序/修改底层的内存分配/对整个代码块做结构调整等,一般不是可以通过代码来解决的)
例:
Stack Overflow Error
OutOfMemeoryError
Exception
定义:
程序应捕获的问题,需要编写者捕获并处理/抛出给调用者处理
处理方式:
- 捕获并处理
- 抛出
①抛出的是RuntimeException及其子类,可以不处理;否则必须捕获或者抛出;
②抛出给调用者,调用者可以继续抛出,也可以捕获处理;
③调用者抛出的异常范围只能大于等于原异常,即原异常及其父类;
④在主函数中抛出异常时,由JVM接收异常(JVM不做捕获,直接打印异常信息);建议不在主函数中抛出异常,尽量抓取,因为抛了也没人再处理了
处理方式1:try…catch…(finally…)
捕获并处理
-
优点:try catch后面的代码可以继续执行
try{ 可能存在异常的代码块 }catch(某种异常e){ 如果捕捉到了e,走到此处,执行解决异常的代码块 }finally{ 即便发生异常也希望执行的代码块,一般是释放资源或关闭连接 }
使用场景:
调用系统方法时,系统方法已经抛出了异常的;
明确可能发生异常的场景;(如涉及用户输入类型不匹配、类型转换、越界等常见异常)
注意事项:
- 只能用当前发生的异常或其父类(exception)捕获;
- 一旦捕捉到异常立刻执行catch中的代码块,try中异常后面的语句都不再执行
- 多个异常顺序发生,只会捕捉到第一个(因为第一个捕捉到之后就跳转到catch了,后面的语句不会再执行,其他异常也不会再发生)
- 多个异常都可能发生(随机发生),可以罗列多个catch进行不同的捕获
- 如何可能存在考虑不到的异常,可将 父类exception在最后 进行捕获
public class Test {
public static void main(String[] args) {
int[] arr={0,1,2};
Random r=new Random();
int index=r.nextInt(4);//0~3
try {
System.out.println(10 / arr[0]);
//可能发生越界异常(index随机到3,int数组最大下标2)
// 或者算术异常(index随机到0,此时除数arr[0]=0)
// }catch (Exception e){
// System.out.println("发生了异常");
// 无法精准表示发生了什么异常
// }
}catch (ArrayIndexOutOfBoundsException d){
//正确写法,在try后罗列多个异常进行处理
System.out.println("越界");
}catch (ArithmeticException f) {
//正确写法,在try后罗列多个异常进行处理
System.out.println("除0");
}catch (Exception e){
System.out.println("未知异常");
//父类只能写在最后,否则会导致其他捕获语句都成为执行不到的语句
}
}
}
public static void main(String[] args) {
Scanner sc=null;
//需要扩大sc的作用域,以便sc在finally中也能使用(如果在try中声明,作用域仅在大括号内)
try{
System.out.println(1/0);//在sc指向对象之前(sc还是空指针的时候)就发生了异常
sc=new Scanner(System.in);
System.out.println("请输入整数");
int num=sc.nextInt();
System.out.println(10/num);
}catch (Exception e){
System.out.println("异常");
}finally {
if(sc!=null)
sc.close();
//必须先判断非空,否则可能会发生空指针异常
//try中如果在sc指向new的scanner对象之前就异常了,sc还是null就走到catch和finally
//此时无法调用任何方法
}
}
处理方式2:throws
只抛出不处理,给调用者进行处理
权限修饰符 特殊关键词 返回类型 方法名 throws 异常类型名称([参数列表]){
方法体
}
- 优点:不同的调用者可以有不同的处理方式,提高代码扩展性
处理方式3:throw
在方法体中抛出指定的异常对象,告知调用者进行处理
public static void main(String[] args){
f(99);
}
public static void f(int index) throws IOException{
if(index>90){
throw new IOException e;
}
}
优点:
在方法体中抛出,可以结合条件语句,在达到不同条件时视作不同异常,抛出不同的异常给调用者处理
注意事项:
throw抛出的如果不是runtime异常,必须再抛给调用者处理;
也就是一般在语句里throw了还要在方法名后面throws
(也可以捕获,但一般不捕获,因为使用throw就一般是调用者传递的参数条件不符合某些范围,所以用该给调用者处理)
继承关系中的异常
父类抛出runtime异常,子类继承并重写父类方法,可以:
- 不抛出不处理 异常;
- 抛出runtime异常及其任意子类异常(如 父类抛 IndexOutOfBoundException,子类抛出 )
父类抛出非runtime异常,子类继承并重写父类方法,可以:
- 不抛出不处理
- 抛出runtime异常及其任意子类异常
- 抛出范围更小的非运行时异常
父类不抛出异常,子类继承并重写父类方法,可以:
- 不抛出不处理
- 抛出runtime异常及其子类
即
抛出Runtime异常及其子类——任意场景下都可以
不抛出异常——任意场景下都可以
抛出非runtime异常——只能在父类抛出的非Runtime异常比子类大时
自定义异常
-
自定义异常类,继承exception
-
重写自定义类的构造函数,直接调用父类的构造函数
即exception(throwable)的构造函数(有参或无参都需要) 有参的可以通过传递异常信息字符串detailMessage,后续捕获时可以获取getMessage 无参的异常信息字符串为空,后续捕获时为NULL
-
在可能发生异常的方法中抛出异常
在方法声明处:throws自定义异常 在方法体中达到一定异常条件时:throw 匿名的自定义异常对象 -调用有参的来创建对象,就会传递异常信息字符串; -调用无参构造函数来创建对象,异常信息字符串就为空,智能打印所属类和发声位置
-
调用方法时捕捉自定义异常,catch中进行处理,信息的打印(调用以下方法:)
printStackTrace:toString+fillInStackTrace(异常发生位置) toString:异常类名+异常信息字符串 getmessage:异常信息字符串
包装类
集合中存放的数据类型必须放包装类~
基本数据类型 | 包装类 | 包装类的方法 |
---|---|---|
int byte short long boolean double char float | Integer Byte Short Long Boolean Double Chatacter Float | intvalue bytevalue bytevalue floatvalue compareTo(返回 1对象比参数大 0相等 -1对象比参数小) 静态变量和方法: Integer.MAX_VALUE int表示的最大范围(short、byte、long都有这个静态变量) Integer.MIN_VALUE int范围的最小范围(short、byte、long都有这个静态变量) Integer.toBinaryString 转换成二进制数 Integer.toOctaclString 转换成8进制数 Integer.toHexString 转换成16进制数 |
装箱与拆箱
Integer i= new Integer(2);//不推荐使用包装类的构造函数装箱,jdk 1.5开始可以自动装箱拆箱
Integer j=4;
//装箱:基本类型→包装类
int k=i.intvalue();//不推荐使用方法拆箱,jdk 1.5开始可以自动装箱拆箱
int m=j;
//拆箱:包装类→基本类型
Integer i=new Integer("234");
//不是装箱,因为右边是String,也是引用类型(这种构造函数调用了parseInt方法,将字符串转换为int)
System.out.println(i-2);
//结果:232
jdk 1.5开始可以自动装箱拆箱,包装类越来越方便替代基本类型;
基本类型/包装类与字符串的转换
基本类型转字符串
int i=1;
-
拼接一个空字符串“”
String s=i+"";
-
基本类型转包装类再toString(返回一个String类型)
Integer i2=i; String s=i2.toString();
-
String类的静态方法valueOf(返回一个String类型)
String.valueOf(i);
字符串转基本类型
包装类的静态方法:各包装类的parse方法/valueOf方法
-
不推荐parseInt 返回int基本类型
int a=Integer.parseInt("234");
-
推荐Integer.valueOf 返回Integer包装类,可以直接继续调方法
int a=Integer.valueOf("234");
注意事项:
非整数形式字符串用上述方法转整数/非数字形式字符串用上述方法转浮点数,会出现NumberFormateException