Java—遇到报错不要慌,教你如何在打印错误信息的同时让程序继续运行。

  • Post author:
  • Post category:java




异常

Java当中对可能出现异常或者错误的的一种描述、信息的对象体现



异常的分类

Throwable

Error: 我们无法处理,例如 内存溢出

Exception: (受检异常) Exception或者Exception的子类但不是RuntimeException的子类称为编译时异常

RuntimeException (运行时异常 非受检异常) RuntimeException或者RuntimeException的子类

异常处理的目的: 能够让程序继续执行,同时打印错误信息\

JVM处理异常的方式

1.打印错误信息

2.终止程序

JVM处理异常不能够满足我们的需求,所以需要自己处理异常

处理异常的方式

1.try…catch…finally

2.throws


处理方式的格式:


	 try {
  		可能处理出现问题的代码
  } catch(异常类名  异常对象) {
 		异常发生后的处理方式
  } catch(异常类名  异常对象) {
  		异常发生后的处理方式
  } ... 



异常处理的执行流程

1.程序执行到 System.out.println(a / b);代码

2.系统会抛出一个异常对象

创建一个异常对象,并且抛出给开发者

ArithmeticException e = new ArithmeticException(“/ by zero”);

throw e;

3.代码进入catch块进行匹配

Exception ae = e; // 多态

4.匹配成功: 程序会转入catch块执行

匹配失败: 程序交还给JVM处理


注意事项:


1.如果程序在try块中出现了异常,那么无论try块下面有多少行代码都不会被执行,执行去和catch块进行匹配

2.异常处理的标准格式

a.能够显示处理的尽量显示处理,提高程序的可读性

b.程序的最后面一定要加上Exception作为父类接受一切异常,提高了程序的健壮性


代码示例

public static void main(String[] args) {
		System.out.println("游戏开始");
		
		int a = 10;
		int b = 0;
		String s = null;
		int[] arr = new int[3];
		Object obj = "张三";
		try {
			// System.out.println(a / b);
			// System.out.println(s.equals("abc"));
			// arr[4] = 10;
			Integer integer = (Integer) obj;
		} catch(ArithmeticException ae) {
			// System.out.println("出问题了,除数为0!");
			ae.printStackTrace();
		} catch(NullPointerException ae) {
			// System.out.println("出问题了,对象不能够为null!");
			ae.printStackTrace();
		} catch(ArrayIndexOutOfBoundsException aioobe) {
			// System.out.println("出问题,数组越界");
			aioobe.printStackTrace();
		} catch (Exception e) {
			// System.out.println("有问题");
			e.printStackTrace();
		}
		
		
		System.out.println("游戏结束");
	}
}



Throwable类

1. 该类是所有异常和错误的超类

2. 只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出

3. 只有此类或其子类之一才可以是 catch 子句中的参数类型



异常链

Throwable initCause(Throwable cause)

将此 throwable 的 cause 初始化为指定值。

Throwable getCause()

返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null



常用方法

Throwable fillInStackTrace() 填充错误信息到堆栈中

Throwable getCause()

返回此 throwable 的 cause;如果 cause 不存在或未知,则返回 null。

String getLocalizedMessage() 获取错误信息 detailMessage

String getMessage() 同上

StackTraceElement[] getStackTrace() 获取堆栈中的错误信息

Throwable initCause(Throwable cause)

将此 throwable 的 cause 初始化为指定值。

void printStackTrace() 输出错误信息到控制台

void printStackTrace(PrintStream s)

void printStackTrace(PrintWriter s)

输出错误信息到 外界 【浏览器 文件 …】

void setStackTrace(StackTraceElement[] stackTrace)

设置将由 getStackTrace() 返回,并由 printStackTrace() 和相关方法输出的堆栈跟踪元素。

String toString() 获取错误类的对象描述 类路径: 错误信息

返回此 throwable 的简短描述。


StackTraccElement 中的常见方法

String getClassName()

返回类的完全限定名,该类包含由该堆栈跟踪元素所表示的执行点。

String getFileName()

返回源文件名,该文件包含由该堆栈跟踪元素所表示的执行点。

int getLineNumber()

返回源行的行号,该行包含由该堆栈该跟踪元素所表示的执行点。

String getMethodName()

返回方法名,此方法包含由该堆栈跟踪元素所表示的执行点。

int hashCode()

返回此堆栈跟踪元素的哈希码值。

boolean isNativeMethod()

如果包含由该堆栈跟踪元素所表示的执行点的方法是一个本机方法,则返回 true。



throws关键字

应用场景:

1.我处理不了

2.我没有权限处理

3.我不想处理

格式:

[修饰符] 返回值类型 方法名(参数列表) [throws 异常类1,异常类2…]{


}

1.该方法抛出异常类,表示抛出调用者处理,谁调用谁处理

2.一个方法可以抛出多个异常

3.如果一个方法抛出的是一个编译时异常,那么必须处理,调用者也必须处理

4.子类继承父类,重写方法,抛出的异常不能够被扩大


代码示例

	public static void main(String[] args) /*throws ArithmeticException */{
		System.out.println("Start");
		
		/*try {
			method();
		} catch (Exception e) {
			e.printStackTrace();
		}*/
		
		try {
			show();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		System.out.println("End");
	}
	
	public static void show() throws ParseException {
		DateFormat df = new SimpleDateFormat("yyyy");
		df.parse("1997");
	}
	
	public static void method() throws ArithmeticException, NullPointerException {
		test();
	}
	
	public static void test() throws ArithmeticException, NullPointerException {
		int a = 10;
		int b = 0;
		System.out.println(a / b);
	}
}

class Father {
	public void show() throws NullPointerException {
		
	}
}

class Son extends Father {
	@Override
	public void show() throws NullPointerException {
	}
}



throw

throw 和 throws的区别

1.throws是在方法的声明上,throw在方法体内

2.throws表示异常出现的一种可能性,throw表示一定出现了异常

3.throws表示声明的是异常类,而throw抛出的是异常对象

4.throws可以抛出多个异常类,而throw只能够抛出一个异常对象


代码示例

	public static void main(String[] args) throws ParseException {
		System.out.println("start");
		
		try {
			method();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("end");
	}
	
	public static void method() throws ArithmeticException {
		int a = 10;
		int b = 0;
		
		// 处理方式 一: 规避异常
		/*if (b != 0) {
			System.out.println(a / b);
		}*/
		
		// 处理方式二: 直面异常
		if (b == 0) {
			// ArithmeticException ae = new ArithmeticException("兄弟,除数不能为0你不知道啊!");
			throw new ArithmeticException("兄弟,除数不能为0你不知道啊!");
		}
		System.out.println(a / b);
		
	}
}



finally

finally修饰的代码块一定会被执行,除非在执行到finally之前程序异常退出或者调用了系统退出的方法。

finally用于释放资源,在IO流操作和数据库操作中会见到。


代码示例

	public static void main(String[] args) {
		int a = 10;
		int b = 0;
		try {
			System.out.println(a / b);
		} catch (Exception e) {
			e.printStackTrace();
			// return;
			System.exit(0);
		} finally {
			// 一般用来释放资源
			System.out.println("finally代码块被执行");
		}
		
		System.out.println("over");
		
				
	}
}



自定义异常

JDK中提供的异常不能够完全满足开发的时候,比如分数在0~100分之外就算异常

这个异常JDK中没有,需要自定义异常


代码示例

	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.print("请输入分数: ");
		
		Double score = input.nextDouble();
		try {
			System.out.println(isLegalScore(score)? "合法":"不合法");;
		} catch (ScoreException e) {
			e.printStackTrace();
		} finally {
			if (input != null) {
				input.close();
			}
		}
		
		System.out.println("批改结束....");
	}
	
	/*
	 * 判断分数是否在0~100分之间
	 */
	public static boolean isLegalScore(Double score) throws ScoreException {
		if (score < 0 || score > 100) {
			throw new ScoreException("兄弟,这个分数是不是改错了!这个" + score + "不行,0~100分之间才可以,例如61分,79分");
		}
		return true;
	} 
}

class ScoreException extends Exception {
	private static final long serialVersionUID = -1989349702073875392L;

	public ScoreException() {}
	
	public ScoreException(String message) {
		super(message);
	}

运行结果:

在这里插入图片描述



版权声明:本文为weixin_45887275原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。