异常:
指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止。
public class ErrorDemo01 {
public static void main(String[] args) {
int[] arr =new int[1024*1024*1024];
System.out.println("hello");
}
}
编译时异常:
public class Demo {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat =new SimpleDateFormat("yyyy-MM-dd");
Date date1 = null;
date1 = simpleDateFormat.parse("2019-09-10");//编译时异常
//要对异常进行处理
/* try {
date1 = simpleDateFormat.parse("2019-09-10");
} catch (ParseException e) {
e.printStackTrace();
}*/
}
}
运行期异常:
public class Demo02 {
public static void main(String[] args) {
//Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
System.out.println(0/0);//运行期异常
}
}
异常的处理:throw、throws、try...catch
throw关键字:
throw关键字必须写在方法内,其创建的异常对象,必须是Exception或者是Exception的子类对象
throw关键字后边创建的异常对象
如果是运行期异常,那么我们不用处理这个异常,交给JVM处理,默认处理方式就是中断处理
如果是编译期异常,那么我们就必须处理这个异常,要么throws继续抛出给别人处理,要么try...catch自己处理
public class ThrowDemo {
public static void main(String[] args) {
method(null);
}
public static void method(Object o){
if(o==null)throw new NullPointerException("对象为null");
}
}
public class ThrowDemo {
public static void main(String[] args) {
int[] arr= new int[]{1,2,3};
method(3,arr);
}
public static void method(int index,int[] arr){
if(index>arr.length-1){
throw new IndexOutOfBoundsException("数组访问越界");
}
}
}
throws关键字
作用:
当方法内部抛出异常对象时,我们可以使用throws关键字处理这个异常对象会继续把异常对象声明抛出给方法的调用者处理
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ThrowsDemo02 {
public static void main(String[] args) throws ParseException {
Date date =new Date();
method(date);
}
private static void method(Date date) throws ParseException {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
date = simpleDateFormat.parse("2018-10-10");
System.out.println(date);
}
}
try...catch
作用:
当方法内部抛出异常对象时,我们可以使用try...catch处理异常对象
好处:程序如果有后续代码,会把异常处理完毕之后继续执行
注意:
1.catch中定义的异常变量是根据try中抛出的异常来定义;一般抛出什么对象,就定义什么异常变量来接收这个异常对象
2.try中可以能会抛出多个异常对象,就可以定义多个catch来分别处理这些异常对象
3.try代码中如果出现了异常,那么就不会继续执行try中的代码,会执行catch中异常的处理逻辑,执行完毕;继续执行try...cath之后的代码
如果没有出现异常,正常执行try中的代码,执行完毕,不会执行catch中异常的处理逻辑,会执行执行try...cath之后的代码
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ThrowsDemo02 {
public static void main(String[] args){
Date date =new Date();
method(date);
}
private static void method(Date date){
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
date = simpleDateFormat.parse("2018-10-10");
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
}
}
好处体现:不影响后续的代码实现
public class ThrowsDemo02 {
public static void main(String[] args){
try{
System.out.println(0/0);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("后续功能");
}
}
Finally代码块
finally:有一些特定的代码无论异常是否发生,都需要执行。另外,因为异常会引发程序跳转,导致有些语句执行
public class ThrowsDemo02 {
public static void main(String[] args){
try{
System.out.println(0/0);
}catch(Exception e){
e.printStackTrace();
}finally {
System.out.println("finally代码块中的语句一定会执行");
}
}
}
Throwable类
Throwable类是Error类和Exception类的父类
Throwable类处理异常的方法:
String getMessage() 返回此 throwable 的简短描述。
String toString() 返回此 throwable 的详细消息字符串。
void printStackTrace() 打印的异常信息是最全面的,JVM默认就是调用此方法打印的异常信息
import java.io.FileNotFoundException;
public class ThrowableDemo01 {
public static void main(String[] args) {
try{
String fileName = "d://a.txt";
method(fileName);
}catch (FileNotFoundException e){
//System.out.println("FileNotFoundException异常");
//String toString() 返回此 throwable 的详细消息字符串。
System.out.println(e.toString());
//String getMessage() 返回此 throwable 的简短描述。
System.out.println(e.getMessage());
//void printStackTrace() 打印的异常信息是最全面的,JVM默认就是调用此方法打印的异常信息
e.printStackTrace();
}
}
private static void method(String fileName) throws FileNotFoundException {
if("c://a.txt".equals(fileName))throw new FileNotFoundException();
}
}
自定义异常类
作用:在开发中根据自己业务的异常情况来定义异常类
例子:登录用户名不能重复
import java.util.ArrayList;
import java.util.Scanner;
class RegisterException extends RuntimeException{
public RegisterException() {
super();//调用父类的空参数构造方法
}
public RegisterException(String message) {
super(message);//调用父类带异常信息的构造方法
}
}
public class MyExceptionDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("王五");
System.out.println("请输入您要注册的用户名:");
String regName= new Scanner(System.in).next();
checkName(list,regName);
}
public static void checkName(ArrayList<String> list,String regName){
//使用Collection集合中的方法contains判断集合中是否包含用户输入的用户名
boolean b = list.contains(regName);
if(b){
//true:抛出一个异常对象,提示"亲,该用户名已经被注册"
throw new RegisterException("亲,该用户名已经被注册!");
}else{
//false:把用户名存储到集合中
list.add(regName);
System.out.println("恭喜您,注册成功!");
}
System.out.println(list);
}
}
多异常的捕获:
1. 多个异常分别处理。
2. 多个异常一次捕获,多次处理。
3. 多个异常一次捕获一次处理。
import java.util.ArrayList;
public class ExceptionDemo {
public static void main(String[] args) {
/* //1、多个异常分别处理
try {
System.out.println(0 / 0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
try{
int[] arr = new int[]{1,2,3};
System.out.println(arr[3]);
}catch (IndexOutOfBoundsException e){
e.printStackTrace();
}*/
/* //2、多个异常一次捕获,多次处理。
try{
System.out.println(0/0);
int[] arr = new int[]{1,2,3};
System.out.println(arr[3]);
}catch (ArithmeticException e){
e.printStackTrace();
}catch (IndexOutOfBoundsException e){
e.printStackTrace();
}*/
//3、多个异常一次捕获,一次处理
try{
int[] arr = {1,2,3};
System.out.println(arr[5]);
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
System.out.println(list.get(10));
}catch (IndexOutOfBoundsException e){
e.printStackTrace();
}
System.out.println("后续代码");
}
}