java学习之路 之 异常处理练习题

时间:2022-12-12 19:39:47
/**
*异常的分类 :
*1) 按照严重程度
*1) Error 严重错误
*2) Exception 普通异常
*2) 按照处理要求来分
*1) 受检异常 : 在程序中必须接受检查和处理的异常
*Exception及其子类(RuntimeException及其子类除外)
*2) 非受检异常 : 在程序中不是必须接受检查和处理的异常
*Error及其子类 (太严重)
*RuntimeException及其子类 (太轻微)
*异常的处理 : 适用于所有异常
*1) 捕获 使用语句try catch finally, 组合法3种, 至少保证要有try,还必须有catch或finally
*2) 抛出 在方法签名中使用throws 可能抛出的异常类型, 在语句块中使用throw 异常对象 真的抛出异常, 产生实质破坏
*3) 先捕获再抛出 先捕获已知异常, 捕获到以后,再把它包装成为其他自定义异常对象, 再抛出自定义异常对象
*
*处理方式的选择 :
*底层方法 :
*抛出异常或捕获再抛出
*顶层方法 :
*捕获
*
*补充点 :
*方法覆盖 : 子类重写父类的方法.
*条件 :
*1) 方法签名必须一致 (返回值类型一致, 方法名一致, 参数列表一致[参数类型一致, 个数一致, 顺序一致]
*2) 访问控制修饰符子类大于等于父类
*3) 子类抛出的受检异常范围小于等于父类
*
*/

@SuppressWarnings("serial")
// 自定义异常, 是受检异常, 是必须对其进行处理的异常
class DevidedByZeroException extends Exception {

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

public DevidedByZeroException(Exception cause) {
super(cause);
}

}

class ExceptionTest5 {

public static int divide(int x, int y) throws DevidedByZeroException {
int z = 0;
try { // 先尝试执行有可能出现异常的代码
z = x / y;
} catch (ArithmeticException e) { // 如果真的出现异常就对其进行包装
// 把系统异常包装为自定义异常, 最终抛出去的是自定义异常对象
throw new DevidedByZeroException(e);
}
return z;
}

public static void main(String[] args) {
try {
int ret = divide(10, 2);
System.out.println(ret);
ret = divide(10, 0);
System.out.println(ret);
} catch (DevidedByZeroException e) {
System.out.println(e);
}
System.out.println("main end");
}
}

class ExceptionTest4 {

// throws 后面可以跟多个不同类型的异常, 用以表示此方法有可能抛出多种异常
// throws Exception 可以统一地把任意异常抛出, 使得抛出异常模糊, 不建议使用
public static int divide(int x, int y) throws DevidedByZeroException, NullPointerException {
int z = 0;
if (y == 0) {
// 主动抛出自定义异常, 必须在方法签名中加入抛出声明
throw new DevidedByZeroException("被0除错误");
}
z = x / y;
return z;
}
/*声明异常类IlleagalNumberException,用来表示无效数字异常
写一个TestException2类,在其中声明int divide(int m, int n)方法,该方法可抛出IlleagalNumberException异常。
方法的两个参数分别为被除数和除数,返回值为商
如果除数为0,则方法抛出IlleagalNumberException异常
改写main方法,调用divide方法计算商值打印输出,并捕获可能出现的异常。*/

//public static void main(String[] args) throws DevidedByZeroException { // 如果在main中抛出异常, 会导致程序极不稳定
public static void main(String[] args) {
System.out.println("main begin");

try {
int ret = divide(10, 2);
System.out.println(ret);
ret = divide(10, 0);
System.out.println(ret);
} catch (DevidedByZeroException e) {
System.out.println(e);
}
System.out.println("main end");
}
}

class ExceptionTest3 { // 避免类名冲突

public static int divide(int x, int y) {
int z = 0;
if (y == 0) {
RuntimeException re = new ArithmeticException("除数为0错误");
throw re; // 只有执行了throw语句后, 方法才异常返回, 和return最大的区别在于 它是带着破坏性的
}
z = x / y;
return z;
}

public static void main(String[] args) {
try {
System.out.println(divide(10, 2));
System.out.println(divide(10, 0));
} catch (ArithmeticException e) {
System.out.println(e);
}

System.out.println("main end...");
}
}

public class ExceptionTest { // 避免类名冲突

@SuppressWarnings("null")
public static void main(String[] args) {
System.out.println("main begin...");

try { // 包围的代码, 有可能抛出异常的语句
int n = Integer.parseInt(args[0]); // 一旦出现异常, 后面的语句没有机会执行, 程序崩溃, 提前结束!!
System.out.println("接收到命令行参数的整数:" + n);
try {
int[] arr = null;
System.out.println(arr.length);
} catch (Exception e) {
System.out.println(e);
}
System.out.println("after inner try");
return;
//} catch (捕获到的异常类型 异常对象) {异常的处理代码}
} catch (ArrayIndexOutOfBoundsException e) {
// 如果真的捕获到指定类型的异常对象进入这里
e.printStackTrace(); // 打印异常对象出现的栈踪迹
} catch (NumberFormatException e) {
System.out.println(e.getMessage()); // 打印异常对象的详细信息
} catch (Exception e) { // 万能夹, 可以捕获任意的其他异常
System.out.println("其他任意可能出现的异常:" + e);
} finally { // 最终地, 末了地... 甚至可以在return语句后执行,截获return
System.out.println("这句话总是会被打印, 无论前面发生了什么!!!, 都不能拦阻");
// 通常会执行一些关闭和操作系统相关的资源的操作. GC只能关闭在GC区中的资源
}

System.out.println("main end..."); // 程序关键代码
}
}

class ExceptionTest2 { // 避免类名冲突

public static void main(String[] args) {
try {
Integer.parseInt(args[0]);
} catch (Exception e) {
e.printStackTrace();
}

try {
Integer.parseInt(args[0]);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("finally");
}

try {
Integer.parseInt(args[0]);
} finally {
System.out.println("finally");
}

/*
catch () {

} finally {

}
*/
}
}

/**
* 编写TestException类,在main方法中接收两个命令行参数,将它们转换为整数,并用第一个数除以第二个数,打印结果。
在命令行运行程序,给出两个参数,测试以下情况,观察运行结果:
其中某个参数不是数字
什么都不传入
第二个参数为0
* @author Administrator
*
*/
public class TestException {

public static void main(String[] args) {
System.out.println("main begin...");

try {
int var1 = Integer.parseInt(args[0]);
int var2 = Integer.parseInt(args[1]);
int var3 = var1 / var2;
System.out.println(var1 + "/" + var2 + "=" + var3);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e); // 相对详细
} catch (NumberFormatException e) {
e.printStackTrace(); // 异常的信息最详细的
} catch (ArithmeticException e) {
System.out.println(e.getMessage()); // 最不详细
} catch (Exception e) {
System.out.println(e);
}

System.out.println("main end...");
}
}

/*声明异常类IlleagalNumberException,用来表示无效数字异常*/
@SuppressWarnings("serial")
class IlleagalNumberException extends Exception {

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

public IlleagalNumberException(Exception cause) {
super(cause);
}
}

class TestException3 {

public static int divide(int m, int n) throws IlleagalNumberException {
try {
return m / n;
} catch (ArithmeticException e) {
throw new IlleagalNumberException(e);
}
}

public static void main(String[] args) {
try {
int num1 = Integer.parseInt(args[0], 16);
int num2 = Integer.parseInt(args[1], 16);
int num3 = divide(num1, num2); // 必须对其进行处理
System.out.println(num1 + " / " + num2 + " = " + num3);
} catch (NumberFormatException e) {
System.out.println(e);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} catch (IlleagalNumberException e) {
System.out.println(e);
} catch (Exception e) {
System.out.println("为保万无一失, 添加这个catch, 可以捕获其他任意异常:" + e);
}
System.out.println("main end");
}
}

/*
* 写一个TestException2类,在其中声明int divide(int m, int n)方法,该方法可抛出IlleagalNumberException异常。
方法的两个参数分别为被除数和除数,返回值为商
如果除数为0,则方法抛出IlleagalNumberException异常
改写main方法,调用divide方法计算商值打印输出,并捕获可能出现的异常。*/
public class TestException2 {

public static int divide(int m, int n) throws IlleagalNumberException {
int q = 0;
if (n == 0) {
throw new IlleagalNumberException("除数为0错误!!!");
}
q = m / n;
return q;
}

public static void main(String[] args) {
try {
int num1 = Integer.parseInt(args[0], 16);
int num2 = Integer.parseInt(args[1], 16);
int num3 = divide(num1, num2); // 必须对其进行处理
System.out.println(num1 + " / " + num2 + " = " + num3);
} catch (NumberFormatException e) {
System.out.println(e);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
} catch (IlleagalNumberException e) {
System.out.println(e);
} catch (Exception e) {
System.out.println("为保万无一失, 添加这个catch, 可以捕获其他任意异常:" + e);
}
System.out.println("main end");
}
}