讲到这个板块,本人相信有丰富编程经验的同学,就会特别注意啦。因为我们编写的代码,随着代码量的增加,出现错误的几率也会增大。但是,一旦我们在一个程序中编写了很多代码,这时候出现错误,就会很头疼,因为有时候改了这边,那边就要出问题。所以,本人现在通过这篇博文来讲解一下,在Java中,我们该如何处理异常。
异常:
概述:
异常就是Java程序在运行过程中出现的错误。
首先,本人来展示一个在C语言中我们经常会出现的问题,在Java中的一种异常——“内存泄漏”
看下段代码:
现在,本人来介绍下 异常的继承体系:
异常的继承体系:
继承体系:
异常的基类: Throwable
- 严重问题: Error 不予处理,因为这种问题一般是很严重的问题,比如: 内存溢出
- 非严重问题: Exception,又分为:
1. 编译时异常: 非RuntimeException(亦或被称为 非运行时异常)
2. 运行时异常: RuntimeException
如果觉得文字描述不太清晰,那么请看下图:
那么,本人就来讲解下这两类异常的区别吧:
两类异常的区别:
编译时异常(非运行时异常)和 运行时异常 的 区别:
- 编译时异常:
Java程序必须显示处理,否则程序就会发生错误,无法通过编译- 运行时异常:
无需显示处理,也可以和编译时异常一样处理
那么,现在本人来介绍下Throwable类:
Throwable类:
概念:
用于 处理异常信息 的类
在这里,本人先来介绍下Throwable这个类中的常用API:
Throwable的常用API:
- getMessage():
获取异常信息,返回字符串。- toString():
获取异常类名和异常信息,返回字符串。- printStackTrace():
获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
那么,现在本人来展示下这个类的使用:
package about_io;
public class Test {
public static void main(String[] args) {
try {
System.out.println(1 / 0);
} catch (ArithmeticException e) {
//这里面,是try里面一旦遇到该异常,就进catch
e.printStackTrace();//打印异常的堆栈信息
String message = e.getMessage(); //获取异常信息
System.out.println(e.toString());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("之后的代码");
}
}
那么,让我们来看一下运行结果:
JVM对于异常的处理方法:
对于异常,JVM的处理方法:
- 自己将该问题解决,然后继续运行
- 自己没有针对的解决方式,只有交给调用main的JVM来处理
JVM有一个默认的异常处理机制:
- 将该异常的名称,异常的信息.异常出现的位置打印在了控制台上,
- 将程序停止运行(即:可认为异常相当于return)
由于本人在下面的讲解中,要处理“除0错”的异常,
所以,本人就通过“除0错”异常来展示下JVM的处理方法:
可以看到:
异常信息被打印在了控制台上,
并且程序在发生异常的那一行停止了,没再运行后面的代码。
现在,本人来告诉大家一个关于“除0错”的一个非常奇怪的知识点:
除0异常只会出现在int型中
下面我们来编写两段代码来验证下:
package com.mec.about_expection;
public class Test {
public static void main(String[] args) {
double num = 1.0;
System.out.println(num / 0.0);
}
}
现在,本人为了更进一步验证“除0错异常”只会出现在int类型中,来编写一个Complex类(即:验证用户自定义类型也不会出现“除0错异常”):
package com.mec.complex;
public class Complex {
private double real;
private double vir;
public Complex(double real, double vir) {
this.real = real;
this.vir = vir;
}
public Complex() {
this(0.0, 0.0);
}
public Complex(Complex c) {
this(c.real, c.vir);
}
public double getReal() {
return real;
}
public void setReal(double real) {
this.real = real;
}
public double getVir() {
return vir;
}
public void setVir(double vir) {
this.vir = vir;
}
public Complex add(Complex c) {
this.real += c.real;
this.vir += c.vir;
return this;
}
public static Complex add(Complex one, Complex another) {
return new Complex (one).add(another);
}
private static Complex opposite(Complex c) {
return new Complex(-c.real, -c.vir);
}
private static Complex reciprocal(Complex c) {
double model = c.real * c.real + c.vir * c.vir;
if(Math.abs(model) < 1e-6) {
return null;
}
return new Complex(c.real / model, -c.vir / model);
}
public Complex sub(Complex c) {
return this.add(opposite(c));
}
public static Complex sub(Complex one, Complex another) {
return new Complex(one).add(opposite(another));
}
public Complex mul(Complex one) {
double real = this.real;
this.real = real * one.real - this.vir * one.vir;
this.vir = real * one.vir - this.vir * one.real;
return this;
}
public static Complex mul(Complex one, Complex another) {
return new Complex (one).mul(another);
}
public static Complex div(Complex one, Complex another) {
Complex rec = reciprocal(another);
return rec == null ? null : new Complex(one).mul(rec);
}
@Override
public String toString() {
return "(" + real + "," + vir + ")";
}
@Override
public boolean equals(Object obj) {
if(null == obj) {
return false;
}
if(this == obj) {
return true;
}
if(!(obj instanceof Complex)) {
return false;
}
Complex c = (Complex) obj;
return Math.abs(this.real - c.real) < 1e-6
&& Math.abs(this.vir - c.vir) < 1e-6;
}
}
在这里,我们能够清晰地看到——没有出现“除0错异常”。
这是为什么呢?
答曰:除0异常只会出现在int型中!
对于异常,我们有两种处理方式:
异常的处理方式:
请观看本人博文——《详解 异常的处理方式》
接下来,本人要讲解一个非常重要的知识点——自定义异常:
自定义异常:
请观看本人博文 —— 《详解 自定义异常》