IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Surpass Day20——Java 异常 -> 正文阅读

[Java知识库]Surpass Day20——Java 异常

目录

1、编译时异常和运行时异常???

1.1 基本概念

1.2 二者区别

1.3 对异常的处理

2、深入try...catch异常

2.1 try...catch的格式

2.2 关于try...catch

2.3 JDK新特性

2.4、上报和捕捉如何选择

3、getMessage()方法和printStackTrace()方法

4、finally子句

5、final、finally和finalize的区别

5.1 final

5.2 finally

5.3 finalize()

6、自定义异常

6.1 自定义异常的步骤

6.2 栈内存程序的改进

7、子类重写的方法抛出编译异常只能更少/小不能更多


1、编译时异常和运行时异常???

1.1 基本概念

译时异常和运行时异常都是发生在运行阶段编译阶段异常不会发生

编译时异常必须在编译(编写)阶段预先处理,如果不处理编译器报错;

所有异常都是在运行阶段发生的,因为只有程序运行阶段才可以new对象。异常的发生就是new异常对象

1.2 二者区别

编译时异常(受检异常、受控异常)发生概率较高,需要在运行之前对其进行预处理;

运行时异常(未受检异常、非受控异常)发生概率较低,运行之前不需要进行预处理;

1.3 对异常的处理

1)在方法声明的位置上,使用throws关键字;【抛给上一级,谁调用我,我就抛给谁;抛给上一级同样有两种方式】

java中异常发生之后如果一直上抛,最终抛给了main方法,main方法继续向上抛,抛给了调用者JVM,JVM终止程序的执行

2)使用try..cathch语句进行异常的捕捉;【这件事发生了谁也不知道,因为我给抓住了】

public class Sttt{
 ? ?public static void main(String[] args) {
 ? ? ? ?System.out.println(100/0);
//程序执行到此发生ArithmeticException异常,底层new了一个ArithmeticException异常对象,然后抛给了main方法,main方法最后无法处理,将异常抛给了JVM,JVM最终终止了程序的执行
 ? ? ? ?System.out.println("helloworld");
 ?  }
}
//ArithmeticException 继承 RuntimeException,属于运行时异常,在编写程序时不需要对这种异常进行预先处理
public class Sttt{
 ? ?public static void main(String[] args)throws ClassNotFoundException//处理方式1 {
        doSome();//因为doSome方法()的声明位置上有 throws ClassNotFoundException 所以在调用的时候要对这种异常进行预先的处理,不处理,编译器会报错
 ? ?
 ?      //Alt + 回车 可以生成
 ?      
 ?      try {
 ? ? ? ? ? ?doSome();
 ? ? ?  } catch (ClassNotFoundException e) {
 ? ? ? ? ? ?e.printStackTrace();
 ? ? ?  }//处理方式2
 ?  }
}
public static void doSome() throws ClassNotFoundException{
//ClassNotFoundException类没找到异常,父类是Exception,所以属于编译时异常
}

3)在抛出异常时,可以抛出该异常的父对象

throws后面可以写多个异常,并且用逗号隔开;

一般不建议在main方法上使用throws,因为这个异常如果真的发生了,一定会抛给JVM,JVM只能终止

异常处理机制的作用就是提高程序的健壮性,保证程序出现了异常也能执行,所以main方法中的异常建议是使用try...catch进行捕捉。main不要继续上抛了

注意:只要异常没有捕捉,采用上报的方式,此方法的后续代码不会执行,另外需要注意:try语句块的某一行出现异常,改行后面的代码不会执行,try catch后续的代码仍然执行

2、深入try...catch异常

2.1 try...catch的格式

try{
 ? ?//try尝试
    m1();
}catch(FileNotFoudException e){
    //catch是捕捉异常之后走的分支
 ? ?System.out.println("文件不存在,可能路径写错了,也可能该文件被删除了");
}

2.2 关于try...catch

1、catch后面的小括号中的类型可以是具体的异常类型,也可以是该异常类型的父类型

2、catch可以写多个,便于程序的调试,catch写多个的时候从上到下,必须遵守从小到大

2.3 JDK新特性

try{
    
}catch(FileNotFoundException|ArithmeticException|NullPointerException e){
?
}

2.4、上报和捕捉如何选择

如果希望调用者来处理,则选择throws上报

3、getMessage()方法和printStackTrace()方法

public class Sttt{
 ? ?public static void main(String[] args) {
 ? ? ? ?//这里为了测试两个方法,而new的异常对象,但是没有吧异常对象抛出,JVM认为是一个普通的java对象
 ? ? ? ?NullPointerException e =new NullPointerException("空指针异常!");
 ? ? ? ?//获取异常简单描述信息:这个信息实际上就是构造方法中的String参数
 ? ? ? ?String msg = e.getMessage();
 ? ? ? ?System.out.println(msg);
 ? ? ? ?e.printStackTrace();//打印异常信息,java后台打印异常堆栈信息的时候采用了异步线程的方式打印的
 ?  }
}

4、finally子句

1)在finally子句中的代码是最后执行的,并且是一定会执行的,即使try语句块的代码出现了异常,

2)finally子句必须和try一起出现,不能单独编写;

3)finally语句通常使用在完成资源的释放/关闭,因为finally语句块中的代码比较有保障,即使try语句块中的代码出现异常,finally中的代码也会正常进行

4)try语句块即使有return,那么finally也会执行,只有当System.exit(0)退出JVM时,才不会执行finally

public class Sttt{
 ? ?public static void main(String[] args) {
 ? ? ? ?FileInputStream fis = null;//声明位置放到try外面,这样才能在finally中使用
 ? ? ? ?try{
 ? ? ? ? ? ?FileInputStream fis = new FileInputStream("D:\\java\javase");
 ? ? ? ? ? ? ? ? ? ?//开始读文件
 ? ? ? ? ? ? ? ? ? ?String s = null;
 ? ? ? ? ? ? ? ? ? ?//这里空指针异常
 ? ? ? ? ? ? ? ? ? ?s.toString();
 ? ? ? ? ? ? ? ? ? ?//流用完需要关闭,因为流是占用资源的
 ? ? ? ? ? ? ? ? ? ?//即使上面程序出现异常,流也必须关系
 ? ? ? ? ? ? ? ? ? ?//放在这里有可能关不了
 ? ? ?  }catch (FileNotFoundException e){
 ? ? ? ? ? ?e.printStackTrace();
 ? ? ?  }catch (IOException e){
 ? ? ? ? ? ?e.printStackTrace();
 ? ? ?  }catch (NullPointerException e){
 ? ? ? ? ? ?e.printStackTrace();
 ? ? ?  }finally {
 ? ? ? ? ? ?//流的关闭放到这里比较保险
 ? ? ? ? ? ?//finally中的代码是一定会执行的
 ? ? ? ? ? ?//即使try中出现了异常
 ? ? ? ? ? ?if(fis != null)//避免空指针异常
 ? ? ? ? ? ? ? ?try{
 ? ? ? ? ? ? ? ? ? ?//close()方法有异常,采用捕捉的方式
 ? ? ? ? ? ? ? ? ? ?fis.close();
 ? ? ? ? ? ? ?  } catch(IOException e){
 ? ? ? ? ? ? ? ? ? ?e.printStackTrace();
 ? ? ? ? ? ? ?  }
 ? ? ?  }
 ?  }
}

5)面试题

java的语法规则:

方法体中的代码必须遵循自上而下顺序依次逐行执行(亘古不变的语法)

return语句一旦执行,整个方法必须结束

public class Sttt{
 ? ?public static void main(String[] args) {
?
 ? ? ? ?System.out.println(m());//结果是100
 ?  }
 ? ?public static int m(){
 ? ? ? ?int i= 100;
 ? ? ? ?try{
 ? ? ? ? ? ?//这行代码出现在 int i = 100;的下面,所以最终结果必须是返回100
 ? ? ? ? ? ?//return 语句还必须保证是最后执行的,一旦执行,整个方法结束
 ? ? ? ? ? ?return i;
 //这里可以理解为自上而下i已经传入了return中但是还没有执行,所以后面的finally无论在return前怎么改变i的值,return i都不会改变
 ? ? ?  }finally{
 ? ? ? ? ? ?i++;
 ? ? ?  }
 ?  }
}

反编译的代码

public static int m{
    int i = 100;
    int j = i;
    i++;
    return j;
}

5、final、finally和finalize的区别

5.1 final

final是一个关键字。表示最终的、不可变的

final int i = 100;

5.2 finally

finally也是一个关键字。和try连用,使用在异常处理机制当中

finally语句块中的代码一定会执行的

try{
?
}finally{
    
}

5.3 finalize()

finalize()是Object类的一个方法,作为方法名出现,所以finalize是标识符

finalize()方法是JVM的GC垃圾回收器负责调用

6、自定义异常

6.1 自定义异常的步骤

第一步:编写一个类继承Exception或者RubtimeException

第二步:写两个构造方法,一个无参构造方法和一个有参构造方法

注意:throw在手动抛异常的时候使用throws表示上报异常信息给调用者

public class Sttt{
 ? ?public static void main(String[] args) {
 ? ? ? ?//new了一个异常对象(没有手动抛出)
        MyException e = new MyException("用户名不能为空");
 ? ? ? ?//打印异常信息
 ? ? ? ? e.printStackTrace();
 ? ? ? ?//获取异常简单描述信息
 ? ? ? ?String msg = e.getMessage();
 ? ? ? ?System.out.println(msg);
 ?  }
}
?
public class MyException extends Exception{
    public MyException(){
        
    }
    public MyException(String s){
        super(s);
    }
}

6.2 栈内存程序的改进

public class Text {
 ? ?public static void main(String[] args) {
 ? ? ? ?//创建一个栈对象,初始化容量是10个
 ? ? ? ?Stack s = new Stack();
 ? ? ? ?s.push("12345ty");
 ? ? ? ?s.push(new Object());
 ? ? ? ?s.push(new Object());
 ? ? ? ?s.push(new Object());
 ? ? ? ?s.push(new Object());
 ? ? ? ?s.pop();
 ? ? ? ?s.pop();
 ? ? ? ?s.pop();
 ? ? ? ?s.pop();
 ? ? ? ?s.pop();
 ? ? ? ?s.pop();
 ? ? ? ?//可以使用for循环进行压栈和弹栈
 ?  }
}
class Stack{
 ? ?//存储任何引用类型数据的数组
 ? ?private Object[] elements;
 ? ?//有参构造方法
 ? ?public Stack(Object[] elements) {
 ? ? ? ?this.elements = elements;
 ?  }
 ? ?//无参构造方法
 ? ?public Stack() {
 ? ? ? ?//一维数组动态初始化
 ? ? ? ?//默认初始化容量为10
 ? ? ? ?this.elements = new Object[10];
 ?  }
 ? ?//栈帧(永远指向栈顶元素)
 ? ?private int index=-1;

//压栈方法
public void push(Object obj) throws MystackQperationException{
 ? ?
 ? ?
 ? ? ? ? ? ? ? ? ? ? ?//重点!!!!!!!!!!!!!
 ? ?if(this.index >= this.elements.length-1){
 ? ? ? ?throw new MystackQperationException("栈内存已满,压栈失败");
 ? ? ? ?//不要进行try...catch,自己new自己抓的操作,必须抛给调用者
 ?  }//这里进行了改进
 ? ? ? ? ? ? ? ? ? ? ?//重点!!!!!!!!!!!!!
 ? ?
 ? ?
 ? ?index++;
 ? ?elements[index] = obj;
 ? ?System.out.println(obj + "元素,压栈成功,栈帧指向" + index);
}
?
//弹栈方法
public void pop() throws MystackQperationException{
 ? ?
 ? ?
 ? ? ? ? ? ? ? ? ? ?//重点!!!!!!!!!!!!!
 ? ?if(this.index <= -1) {
 ? ? ? ?//System.out.println("栈内存已空,弹栈栈失败");
 ? ? ? ?throw new MystackQperationException("栈内存已空,弹栈栈失败"); ?
 ?  }
 ? ? ? ? ? ? ? ? ? ?//重点!!!!!!!!!!!!!
 ? ?
 ? ?
 ? ?else
 ? ? ? ?System.out.println(elements[index] + "元素,弹栈成功,栈帧指向" + --index);
}
//自定义栈操作异常
public class MystackQperationException{
 ? ?public MystackQperationException{
 ? ? ? ?
 ?  }
 ? ?public MystackQperationException(String s){
 ? ? ? ?super(s);
 ?  }
}
//static实例变量的get方法
public Object[] getElements() {
 ? ?return elements;
}
//static实例变量的set方法
public void setElements(Object[] elements) {
 ? ?this.elements = elements;
}
//实例变量栈帧的get方法
public int getIndex() {
 ? ?return index;
}
//实例变量栈帧的set方法
public void setIndex(int index) {
 ? ?this.index = index;
}
}

7、子类重写的方法抛出编译异常只能更少/小不能更多

class Animal{
    public void doSome(){
    
    }
    public void doOther() throws Exception{
    
    }
}
class Cat extends Animal{
    public void doSome() throws Exception{
        //编译报错
    }
 ? ?public void doOther() throws Exception{
        //编译正常
    }
 ? ?public void doOther(){
        //编译正常
    }
 ? ?public void doOther() throws NullPointerException{
        //编译正常
    }
 ? ?public void doSome() throws RuntimeException{
        //运行编译子类可以正常抛出更多,而编译异常不行
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-01-17 11:22:16  更:2022-01-17 11:22:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 9:19:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码