现阶段遇到的异常 JVM(java虚拟机)遇到异常后处理方式: 1.先确定异常的类型,到类库中实例化一个该异常类型的对象 2.看程序员(代码中)是否捕获此异常 没有捕获: 将异常信息直接打印到控制台中 有捕获: 程序员处理
package MONA.demo01_异常;
public class Demo01 {
static String s;
public static void main(String[] args) {
int a = 10;
int b = 0;
//ArithmeticException: / by zero:除以0异常
//System.out.println(a / b);
//NullPointerException :空指针
//System.out.println(s.length());
//ArrayIndexOutOfBoundsException:角标越界异常
int[] arr = new int[1];
System.out.println(arr[2]);
}
}
什么是异常?
异常就是Java程序在运行过程中出现的错误
异常的由来
问题也是显示生活中一个具体事务,也可以通过Java类的形式进行描述。
并封装成对象,其实就是Java对不正常情况进行描述后的对象体现。
例如:
医院的病种
异常的继承体系
在Java中使用Exception类来描述异常。Exception 类及其子类是 Throwable 的一种形式,它用来表示Java程序中可能会产生的异常,并要求对产生的异常进行合理的异常处理。
Exception有继承关系,它的父类是Throwable。Throwable是Java 语言中所有错误或异常的超类。
异常类继承结构图
- Throwable(类)
- Error(错误):由JVM抛出,但不需要程序捕获,因为捕获了也没办法继续运行了;(比如堆栈溢出)
- Exception(异常):程序本身可以处理的异常
- 运行时异常:都是RuntimeException及其子类,如空指针、下标越界,这些异常是可以选择捕获处理,也可以不处理,一般是由程序逻辑引起的错误,应该从逻辑角度尽可能避免这类异常的发生
- 非运行时异常(编译时异常):RuntimeException以外的异常,从程序角度是必须进行处理的异常,如果不处理,那么编译就不能通过,如IOException;
注意:异常和错误的区别:异常能被程序本身可以处理,错误是无法处理。
演示错误的代码1:
package MONA.demo01_异常;
import java.util.ArrayList;
/**
* 演示错误
* 堆栈溢出:StackOverflowError
*/
public class Demo03 {
static ArrayList arr = new ArrayList<>();
public static void main(String[] args) {
add();
}
public static void add(){
arr.add("111");
add();
}
}
编译器异常
package MONA.demo01_异常;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* 编译器异常
*/
public class Demo02 {
public static void main(String[] args) throws ParseException {
String date = "2002年10月09日";
DateFormat df = new SimpleDateFormat();
//df.parse(date);
//错误
int[] arr = new int[1024*1024*100];
}
}
throw 抛出异常1
运行代码:
package MONA.demo01_异常;
public class Demo05 {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
int value = ArrayTools.getElement(arr,3);
System.out.println(value);
}
}
被使用的代码:
package MONA.demo01_异常;
public class ArrayTools {
/**
*获取数组中的指定下标的值
* 此方法会发生两个异常:
* NullPointerException
* ArrayIndexOutOfBoundsException
*/
public static int getElement(int[] arr,int index){
//方法出现错误时,给调用者一个更具体的提示
if(arr == null){
//抛出异常 NullPointerException
//1.创建异常对象
NullPointerException e = new NullPointerException("arr不能为null");
//2.使用throw抛出异常
throw e;
}
//处理越界异常
if(index < 0 || index >= arr.length){
//抛出 ArrayIndexOutOfBoundsException越界异常
ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("错误的下标["+index+"]");
throw e;
}
return arr[index];
}
}
throw 抛出异常2
运行代码:
package MONA.demo01_异常;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class Demo06 {
public static void main(String[] args) throws ParseException{
m1();
}
/**
* df.parse(date);抛出异常
* 有时候我们不想处理此异常
* throws关键字抛出异常
* 让调用者来处理此异常
*/
public static void m1() throws ParseException {
String date = "2019年1月1日";
DateFormat df = new SimpleDateFormat();
df.parse(date);
}
}
被使用的代码:
package MONA.demo01_异常;
import java.text.ParseException;
public class ArrayTools {
/**
*获取数组中的指定下标的值
* 此方法会发生两个异常:
* NullPointerException
* ArrayIndexOutOfBoundsException
*/
public static int getElement(int[] arr,int index)throws ParseException {
//方法出现错误时,给调用者一个更具体的提示
if(arr == null){
//抛出异常 NullPointerException
//1.创建异常对象
NullPointerException e = new NullPointerException("arr不能为null");
//2.使用throw抛出异常
throw e;
}
//处理越界异常
if(index < 0 || index >= arr.length){
//抛出 ArrayIndexOutOfBoundsException越界异常
ArrayIndexOutOfBoundsException e = new ArrayIndexOutOfBoundsException("错误的下标["+index+"]");
throw e;
}
if(true){
//抛出的是编译器异常,所以在方法声明处必须使用throws关键字声明
//方法抛出了此异常parseException
ParseException parseException = new ParseException("我是异常",1);
throw parseException;
}
return arr[index];
}
}
异常捕获及其执行流程(单catch):
如果catch括号里面的异常类型跟try里的异常类型不对应,将不能捕获,即不会跳转到catch。
package MONA.demo01_异常;
/**
* 异常捕获
*/
public class Demo07 {
public static void main(String[] args) {
/*
try{
可能出现异常的代码
}catch(异常类型 变量名){
//异常的处理
}
*/
String s = null;
System.out.println("try之外的代码");
try {
System.out.println("异常之前的代码");
System.out.println(s.length());
System.out.println("异常之后的代码");
}catch (NullPointerException e){//针对空指针异常进行处理
System.out.println("发生了空指针异常");
}
System.out.println("程序结束!!!");
/*
执行流程:
无异常:(catch没有执行)
try 之前的代码
异常之前的代码
执行可能出现异常的代码(没有出现异常)
异常之后的代码
程序结束!!!
有异常:
try 之外的代码
异常之前的代码
try 里面的代码(某一行发生了异常)
跳转catch,执行catch里面的代码(如果捕获了异常)
try后续的代码 (程序结束!!!)
*/
}
}
多catch捕获异常:
package MONA.demo01_异常;
/**
* 多catch
*/
/*
try{
//可能出现多个异常的代词
}catch (异常类型1 e){
//处理异常类型1
}catch (异常类型2 e){
//处理异常类型2
}
*/
public class Demo08 {
public static void main(String[] args) {
String s = null;
int[] arr = {1,2};
try{
System.out.println(10/0);
System.out.println(s.length());
System.out.println(arr[10]);
}catch (NullPointerException e){
System.out.println("发生了空指针");
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("发生了越界异常");
}catch (ArithmeticException e){
System.out.println("除0异常");
}
System.out.println("程序结束");
}
}
注意:这种异常处理方式,要求多个catch中的异常不能相同,并且若catch中的多个异常之间有子父类异常的关系,那么子类异常要求父类异常最上面。
父类拥有所有处理子类异常的能力
try{
异常代码
}catch (子类异常类型1 e){
子类1处理代码
}catch (子类异常类型2 e){
子类2处理代码
}catch (父类异常类型 e){
父类处理代码
}
try ... catch ... finally
package MONA.demo01_异常;
/**
try{
可能会发生异常的代码
}catch (异常类型 e){
异常处理
}finally {
我无论是否发生异常,都会执行
}
*/
public class Demo10 {
public static void main(String[] args) {
String s = null;
try{
//打开了文件
System.out.println(s.length());
}catch (NullPointerException e){
System.out.println("发生空指针");
}finally {
//无论如何,都会执行
System.out.println("我无论是否发生异常,都会关闭文件");
}
System.out.println("程序结束");
}
}
jdk7异常处理方式
package MONA.demo01_异常;
/**
* jdk7 同时处理多个异常
*
* 语法:
* try{
* //可能发生异常的代码
* }catch(异常类型1 | 异常类型2 变量名){
* //多个异常处理方式
* }
*/
public class demo11_异常_jdk7处理方式 {
public static void main(String[] args) {
String s = null;
int[] arr = {1,2};
try{
System.out.println(arr[10]);
System.out.println(s.length());
}catch (NullPointerException | ArrayIndexOutOfBoundsException e){
System.out.println("发生了异常");
//也可以针对异常类型进行判断
// if(e instanceof NullPointerException){
//
// }
// if(e instanceof ArrayIndexOutOfBoundsException){
//
// }
}
System.out.println("程序结束");
}
}
继承中父子类方法抛出异常问题
子类覆盖父类方法时,如果父类的方法声明异常,子类只能声明父类异常或者该异常的子类,或者不声明。
package MONA.demo12_异常_父子类方法;
import java.text.ParseException;
public class Demo {
}
class Fu{
public void show() throws RuntimeException{
System.out.println("show");
}
}
class Zi extends Fu{
public void show()throws ArrayIndexOutOfBoundsException{ }
//错误示范
// public void show()throws ParseException{
//
// }
}
throwable常用方法
package MONA.demo13_异常_throwable;
public class Demo {
public static void main(String[] args) {
String s = null;
try{
System.out.println(s.length());
}catch (NullPointerException e){
String msg = e.getMessage();
System.out.println("msg = "+msg);
String toString = e.toString();
System.out.println("toString ="+toString);
System.out.println("==============================");
//打印异常堆栈信息
e.printStackTrace();
System.out.println("==============================");
//想要打印异常的信息
System.out.println("空指针");
}
}
}
快速生成异常相关代码:
选中可能发生异常的代码再使用快捷键
快捷键:Ctrl+Alt+T
自定义异常
第一部分:测试类
package MONA.demo15_异常_自定义异常;
/**
* 自定义异常
* Java中提供了很多异常
* 在开发中,也会出现很多异常
* 人的年龄
* 自定义:年龄不合法异常
*
*/
public class Demo {
public static void main(String[] args) {
Student s = new Student();
try {
s.setAge(1000);
} catch (AgeException e) {
e.printStackTrace();
System.out.println("发生异常了");
}
}
}
class Student{
String name;
int age;
public void setAge(int age) {
if(age<0 || age>150){
//年龄不合法 抛出年龄不合法异常
AgeException e = new AgeException("年龄不合法");
throw e;
}
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
}
第二部分:自定义异常
package MONA.demo15_异常_自定义异常;
/**
* 自定义异常:
* 1.新建类
* 2.继承异常类
* 3.提供构造方法,传递异常信息
*/
public class AgeException extends RuntimeException{
public AgeException(String msg){
//调用父类的构造方法
super(msg);
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)