一.异常:
1. 定义: 在程序运行过程中发生的异常事件,会终止程序的执行,影响正常运行.
2. 异常处理/异常捕获: 为了不影响程序的正常运行,需要对程序实现try {}catch(){}操作
3. 异常的步骤: 抛出异常–捕获异常–处理异常
4. 异常的关键字:
Try:将可能发生的异常使用它,不能单独写
catch: 捕获异常,不能单独写,必须和try一起使用 ,可以写多个catch ,捕获的异常类必须从小到大排列 ,捕获到相应的异常对象才会执行
finally: 最终执行的代码块 , 无论是否发生异常 都会执行它
throws: 定义要抛出的异常 ,写在方法后面
throw: 抛出异常
/**
*
- @author dch
*/
public class Test {
public static void main(String[] args) {
try{
Scanner scanner = new Scanner(System.in);
System.out.println("请输出2个数");
int a = scanner.nextInt();
int b = scanner.nextInt();
System.out.println("计算a/b: "+a/b);
}catch(ArithmeticException e){
System.out.println("除数不能为0");
}catch(Exception e1){
System.out.println("出错了");
}finally{
System.out.println("程序最后一步");
}
System.out.println("程序结束");
}
/*这里的try{}catch(){}异常处理
*
* 就是为了解决因为程序过程中的异常事件,会终止程序的执行
* 影响正常运行,简单的说就是有错,下面的代码就无法执行.
*
* 异常的步骤
* 抛出异常--捕获异常--处理异常
*
* 这里的finally:最终都要执行的代码块,无论是否发生异常
*
* 可以多个catch从而来捕获多个异常
* 但是也可以写一个总的Exception
*
*
* finally 和 return 的 执行顺序
* 情况一: 先执行finally 再执行 return
*
* 特殊情况: 当方法有返回值值,finally最后执行的结果不影响返回值的
*
*
*
*
* */
}
/**
*
- @author dch
*/
//方法里面的try…catch
public class Test1 {
public static void main(String[] args) {
try{
//代码块
try{
}catch(Exception ee){
}
try{
}finally{
}
// 代码块
System.out.println("hello");
}catch(Exception ee){
try{
}catch(ArithmeticException e1){
}catch(NullPointerException e2 ){
}
}
Test1 test1 = new Test1();
test1.method2();
System.out.println("程序结束");
}
public void method2(){
try{
System.out.println("method2.。。。");
//调用method1
method1();
}catch(Exception ee){ // 是否能将被捕获
System.out.println("除数为0 ");
}
}
// 异常捕获在 方法中 异常的传递
public void method1(){
int num1 =10/0; //方法没有捕获异常时 ,
//自动将异常往上级抛出.
}
}
finally和return 的执行顺序?
无论是try的return 还是 catch的return,都优先执行finally,但是finally不会改变他们预先运行的结果 ,如果finally中有return,则优先其他语句块的return.
/**
*
- @author dch
*/
//try catch 中 Finally和Return的执行前后顺序.
public class TestFinallyReturn {
public static void main(String[] args) {
System.out.println("方法的结果:"+method3());
System.out.println("方法4的结果:"+method4());
}
/**
* finally 和 return 的 执行顺序
* 情况一: 先执行finally 再执行 return
*
* 特殊情况: 当方法有返回值值,
* finally最后执行的结果不影响返回值的值
*
*
*/
public static int method3(){
int num=0;
int num2=1;
try{
num++;
// System.out.println(num/0);
return num; //此时num=1 这里输出的还是1
}catch(Exception e){
//被捕获
System.out.println("除数为0 ");
System.out.println("catch的num:"+num);
System.out.println(num2);
// 返回值前先执行以下 finally
return num;
}finally{//但是这里还是要执行
num++; // finally最后执行是 对返回值没有影响 num=2
num2++;
System.out.println("finally---"+num);
System.out.println("这是finally语句块 ");
return num;
}
}
public static int method4(){
int num=0;
int num2=1;
try{
num++;
// System.out.println(num/0);
return num++; // 2
}catch(Exception e){
//被捕获
System.out.println("除数为0 ");
System.out.println("catch的num:"+num);
System.out.println(num2);
// 返回值前先执行以下 finally
return num;
}finally{
System.out.println(num);//
num++; // finally最后执行是 对返回值没有影响 3
num2++;
System.out.println("finally---"+num);
System.out.println("这是finally语句块 ");
return num;
}
}
/*a++和++a的区别 int a = 0;
*
*
* a++是先执行表达式后再自增,执行表达式时使用的是a的原值。
* ++a是先自增再执行表达示, 执行表达式时使用的是自增后的a
*
*
* */
}
二.异常的分类:
一种是Error异常:
Error指的就是错误,通常是程序员不可能通过代码来解决的问题,底层环境或硬件问题,也可以说是JVM虚拟机发生错误等不能挽回的时间,因此在程序中用户不用捕获Error以及任何Error子类的异常.
Error类包括:
linkkageError(结合错误)
VitualmachineError(虚拟机错误)
Exception类:
-
运行时异常 :在运行过程中发生的错误,可以编译通过
ArithmeticException 算术异常
IllegalArgumentException 参数不合法异常
ArrayIndexOutOfBoundException 数组下标越界异常
ArrayStoreException存入数组的内容数据类型不一致异常
NumberFormatException字符串转换数值所产生的错误
StringIndexOutofBoundException 字符串下标越界异常
IndexOutOfBoundsException索引超出范围的异常
NullPointerException 空指针异常
EOFException : 文件操作突然中止异常 -
非运行时异常(检查异常): 编译不通过,必须手动处理的异常
ClassNotFoundException 找不到类或接口异常
IOException : 文件读写长
SQLException : SQL操作异常
illegaAccessException:类定义不明确异常
InterruptedException : 线程中断异常
三.声明异常和抛出异常
3. 声明throws: 声明一个方法中可能会抛出的异常,对于运行异常不用声明,检查异常需要声明
4. 抛出异常:
5. throw 主动 抛出一个异常 (运行时异常,不需要声明)
throw new ArithmeticException(“除数不能为0”);
对于 运行时异常,不用声明 ,直接抛出
对于 检查时异常,抛出的异常 需要声明
方法的调用则也必须手动处理(继续抛出,catch)
/**
*
- 申明异常,抛出异常
- @author dch
*/
public class TestShenMin {
public static void main(String[] args) {
try {
method1();
} catch (ArithmeticException e) {
System.out.println(e.getMessage());
}
try {
method4();
} catch (Exception e1) {
System.out.println(e1.getMessage());
}
}
//定义method1方法
// 对于运行时异常,不用声明, 直接抛出.
public static void method1(){
System.out.println("输入一个不为0的数");
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
if(a==0){
//主动 抛出一个异常(运行时异常,不需要声明)
throw new ArithmeticException("除数不能为0");
//throw new SQLException();
}
System.out.println(10/a);
}
/**
*对于 检查时异常,抛出的异常 需要声明
* 所谓声明就是在方法后面加上 throws + 检查时异常
*
*/
public static void method2() throws ClassNotFoundException{
//当类不存在的时候,主动产生了一个异常
Class.forName("extends");
}
public static void method3() throws Exception{
method2();
}
public static void method4(){
try {
method3();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
//它处理不了这个异常,也可以继续往外抛
throw new NullPointerException("异常太大");
}
}
}
四.自定义异常
Java允许创建自己定义的异常类,只需满足它是Throwable的子类或间接子类即可
自定义异常主要用于封装项目中的业务提示消息,根据不同的消息对应不同的处理逻辑
自定义异常步骤:
创建一个类继承 Exception/Throwable
封装setMessage消息
第一种
/**
*
- @author dch
*/
//自定义异常,运行异常,不需要声明,只用抛出的那种,继承算术异常的类
public class MyException extends ArithmeticException {
public MyException(){
super("除数不能为0");
}
}
/**
*
- @author dch
*/
//测试类
public class ZDYTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
method1();
} catch (Exception e) {
// TODO: handle exception
System.out.println("除数为0");
}finally{
System.out.println("程序结束");
}
try {
method2();
} catch (MyException1 e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}
}
public static void method1(){
System.out.println("请输入一个数");
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
if(a==0){
throw new MyException();
}
}
//编译时出错,检查异常,需要声明
public static void method2() throws MyException1{
System.out.println("输入用户ID");
Scanner sc = new Scanner(System.in );
String a = sc.nextLine();
for (int i = 0; i < arr.length; i++) {
if(arr[i].equals(a)){
throw new MyException1(1, "");
}
}
System.out.println("请输入取的金额");
int money = sc.nextInt();
if(money>20000){
throw new MyException1(2, "");
}
System.out.println("请输入0");
int num = sc.nextInt();
if(num==0){
throw new MyException1(3,"这个数不能为0");
}
}
}
/**
*
- @author dch
*/
//自己定义异常
public class MyException1 extends Exception {
private int type;
public MyException1(int type, String msg){
super(msg);
this.type=type;
}
//重写
public String getMessage(){
if(type==1){
return "用户id重复";
}if(type==2){
return "金额不能超过2W";
}else{
return super.getMessage();
}
}
}