背景:在程序员使用编译器编码时,总会看到一些红色波浪线标记的异常提示,有些总会要使用throws关键字抛出exception,或者使用try...catch捕获异常自己处理,这是编译时异常,java虚拟机检查语法错误时的异常。那么还有一种问题就是程序底层跑出来的错误error,这种是没法处理的,是需要修改代码的。例如以下异常信息:NullPointerException、IndexOutOfBoundsException、IllegalArgumentException等等异常,编译时语法是没错的,但是运行时就会报错runtimeException,下面来通过代码解释:

1、编译时异常,下面的代码在贴出来时就处理了,通过throws关键字来使程序编译正确,你也可以去掉看看异常提示:

import java.sql.*;

/**
 * java程序运行时发生两种问题 :
 * 一种异常exception 这是一种可处理的异常,是直接从java虚拟机发生的,是java虚拟机运行过程中发生的问题
 * 一种错误error 这种问题发生后不处理,是系统底层发生的,告诉java虚拟机:比如内存溢出,一旦发生错误必须修改代码
 *
 * java程序异常抛出异常的场景: java虚拟机编译时,检查java语法错误;
 * 
 * 运行时异常,就是编译通过了
 * 
 * @ClassName:ExceptionDemo.java
 * @author : Administrator
 * @date : 2019年3月27日 上午10:12:16
 * 
 */
public class ExceptionDemo {

	// 创建数据连接,方法返回类型是Connection
	public Connection getConn() throws SQLException {

		Connection conn = null;
		// 连接url
		String url = "jdbc:mysql://自己mysql服务器的ip:访问端口";
		String user = "root"; // 用户名
		String password = "****"; // 密码
		// useSSL 运行时会提示: WARN: Establishing SSL connection without server's
		// identity verification is not recommended.所以在url后拼接参数useSSL
		conn = DriverManager.getConnection(url + "?useSSL=false", user,
				password);

		// 返回一个连接
		return conn;
	}

	// 调用已申明抛出异常的方法,调用者也需要抛出异常或try catch捕获
	public void withdraw(int money) throws SQLException {
		getConn();
	}

	// 主方法,调用有异常的方法,同样需要抛异常给程序,或者try catch自己处理,;
	// try..。catch可以没有catch,但是catch不能没有try;
	// catch是抓的try执行语句时的异常,如果有才会执行。
	// finally 不管什么问题,都会执行,所以这里可以用来释放一些资源。
	public static void main(String[] args) {

		ExceptionDemo ed = new ExceptionDemo();
		try {
			System.out.println("捕获调用withdraw方法");
			// ed.queryResult();
			ed.withdraw(123);
			// 这句,是上面调用程序没有异常时才会执行。
			System.out.println("执行withdraw方法之后结果:");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			// catch 是处理异常的
			e.printStackTrace(); // 打印程序抛出的异常信息
			// System.out.println(e.getMessage());
			// System.out.println("自己处理");
		} finally {
			System.out.println("不管前面抛出什么异常,最后该语句仍会被执行");
		}

	}
}

2、运行时异常,很常见的问题,下面先看看异常信息:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.java.exception.RuntimeExceptionDemo.main(RuntimeExceptionDemo.java:20)

java.lang.ArrayIndexOutOfBoundsException: 3
	at com.java.exception.RuntimeExceptionDemo.main(RuntimeExceptionDemo.java:33)

3、根据异常得知代码错误,第一个是运算错误,除数是不能为零的,第二个必是数组的角标的越界。

public class RuntimeExceptionDemo {

	// 运行时异常
	public static void main(String[] args) {
		// 下面的代码编译并没有什么问题。正常的申明变量和运算结果,但是并没有运行
		int a = 10;
		int b = 0;
		int c;

		// 这里的代码没有try捕获异常时,然后运行会报ArithmeticException异常
		c = a / b;
		System.out.println(c);

		int[] abc = { 1, 2, 3 };

		// 第二个运行时异常

		for (int i = 0; i < abc.length + 1; i++) {
			System.out.println("打印角标" + i + "对应的元素" + abc[i]);
		}

	}
}

4、那么对已知或未知的代码异常,如何处理了?再有我们并不知道程序运行时会抛什么异常,这里我们使用Exception父类:

public class RuntimeExceptionDemo {

	// 运行时异常
	public static void main(String[] args) {
		// 下面的代码编译并没有什么问题。正常的申明变量和运算结果,但是并没有运行
		int a = 10;
		int b = 0;
		int c;

		// 这里的代码没有try捕获异常时,然后运行会报ArithmeticException异常
		try {
			c = a / b;
			System.out.println(c);
		} catch (Exception e) {
			System.out.println("错误信息描述:"+e.getMessage()+"\n");
		}

		int[] abc = { 1, 2, 3 };

		// 第二个运行时异常
		try {
			for (int i = 0; i < abc.length + 1; i++) {
				System.out.println("打印角标" + i + "对应的元素" + abc[i]);
			}
			// 因为运行过知道是角标越界的异常:ArrayIndexOutOfBoundsException,正常情况我们并不知道会是什么错,所以使用异常的父类Exception来处理
		} catch (Exception e) {
			// e.printStackTrace();
			System.out.println("\n超出数组不存在的角标:" + e.getMessage());
		}

	}
}

5、所以编程开发,弄懂异常是什么,该怎么处理,就很重要了,方便定位问题。再有捕获异常的try...catch...finally,尝试不同组合,把相关的异常运行打印出来。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐