[关闭]
@liayun 2016-05-25T15:56:25.000000Z 字数 9276 阅读 1331

面向对象——异常

java基础


异常:就是程序在运行时出现的不正常情况。
异常的由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象。异常其实就是java对不正常情况进行描述后的对象体现。

异常的体系

对于问题的划分有两种:一种是严重的问题,一种是非严重的问题。

无论Error或者Exception都具有一些共性内容,比如:不正常情况的信息,引发原因等。

异常的处理

java提供了特有的语句进行处理:

  1. try {
  2. 需要被检测的代码;
  3. } catch(异常类 变量) {
  4. 处理异常的代码;(处理方式)
  5. } finally {
  6. 一定会执行的语句;
  7. }

对捕获到的异常对象进行常见方法操作

例,

  1. class Demo {
  2. int div(int a, int b) throws Exception { // 在功能上通过throws的关键字声明了该功能有可能会出现问题
  3. return a/b; // new ArithmeticException();
  4. }
  5. }
  6. class ExceptionDemo {
  7. public static void main(String[] args) {
  8. Demo d = new Demo();
  9. try {
  10. int x = d.div(4, 1); // new ArithmeticException();
  11. System.out.println("x="+x);
  12. } catch(Exception e) { // Exception e = new ArithmeticException();
  13. System.out.println("除零啦!");
  14. System.out.println(e.getMessage()); // / by zero
  15. System.out.println(e.toString());// 异常名称:异常信息
  16. e.printStackTrace(); // 异常名称,异常信息,异常出现的位置
  17. // 其实JVM默认的异常处理机制,就是在调用printStackTrace(),打印异常在堆栈中的跟踪信息
  18. }
  19. System.out.println("over");
  20. }
  21. }

在函数上声明异常(throws)。便于提高安全性,让调用者进行处理,不处理编译失败。

对多异常的处理

  1. 声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
  2. 对方声明几个异常,就对应有几个catch块,不要定义多余的catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最后。

建议在进行catch处理时,catch中一定要定义具体处理方式。不要简单定义一句:e.printStackTrace();,也不要简单的就书写一条输出语句。
例,

  1. class Demo {
  2. int div(int a, int b) throws ArithmeticException, ArrayIndexOutOfBoundsException { // 在功能上通过throws的关键字声明了该功能有可能会出现问题
  3. int[] arr = new int[a];
  4. System.out.println(arr[4]);
  5. return a/b; // new ArithmeticException();
  6. }
  7. }
  8. class ExceptionDemo {
  9. public static void main(String[] args) {
  10. Demo d = new Demo();
  11. try {
  12. int x = d.div(5, 0); // new ArithmeticException();
  13. System.out.println("x="+x);
  14. } catch(ArithmeticException e) {
  15. System.out.println(e.toString());
  16. System.out.println("除零啦!");
  17. } catch(ArrayIndexOutOfBoundsException e) {
  18. System.out.println(e.toString());
  19. System.out.println("角标越界啦!");
  20. } catch(Exception e) {
  21. System.out.println("haha:"+e.toString());
  22. }
  23. System.out.println("over");
  24. }
  25. }

自定义异常

因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。 所以对于这些特有的问题可以按照java的对问题封装的思想,将特有的问题,进行自定义的异常封装。
当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。要么在内部try catch处理,要么在函数上声明让调用者处理。一般情况下,函数内出现异常,函数上需要声明。
自定义异常如何定义异常信息?
答:因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递给父类,通过super语句,那么就可以直接通过getMessage()获取自定义的异常信息。
自定义异常,必须是自定义类继承Exception。继承Exception的原因:异常体系有一个特点,因为异常类和异常对象都被抛出,它们都具备可抛性,这个可抛性是Throwable这个体系中独有的特点,只有这个体系中的类和对象才可以被throwsthrow操作。
throwsthrow的区别:

例,

  1. /*
  2. 需求:在本程序中,对于除数是-1,也视为是错误的,是无法进行运算的,那么就需要对这个问题进行自定义的描述
  3. */
  4. class FuShuException extends Exception {
  5. private int value;
  6. FuShuException() {
  7. super();
  8. }
  9. FuShuException(String msg, int value) {
  10. super(msg);
  11. this.value = value;
  12. }
  13. public int getValue() {
  14. return value;
  15. }
  16. }
  17. class Demo {
  18. int div(int a, int b) throws FuShuException {
  19. if(b < 0)
  20. throw new FuShuException("出现除数是负数的情况----- / by fushu", b); // 手动通过throw关键字抛出一个自定义异常对象
  21. return a/b;
  22. }
  23. }
  24. class ExceptionDemo2 {
  25. public static void main(String[] args) {
  26. Demo d = new Demo();
  27. try {
  28. int x = d.div(4, -9);
  29. System.out.println("x="+x);
  30. } catch(FuShuException e) {
  31. System.out.println(e.toString());
  32. // System.out.println("除数出现负数了");
  33. System.out.println("错误的负数是:"+e.getValue());
  34. }
  35. System.out.println("over");
  36. }
  37. }

RuntimeException

Exception中有一个特殊的子类异常RuntimeException(运行时异常)。

自定义异常时:如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException
对于异常分两种:

例,

  1. class FuShuException extends RuntimeException {
  2. FuShuException(String msg) {
  3. super(msg);
  4. }
  5. }
  6. class Demo {
  7. int div(int a, int b) {
  8. if(b < 0)
  9. throw new FuShuException("出现了除数为负数啦!");
  10. if(b == 0)
  11. throw new ArithmeticException("被零除啦!");
  12. return a/b;
  13. }
  14. }
  15. class ExceptionDemo3 {
  16. public static void main(String[] args) {
  17. Demo d = new Demo();
  18. int x = d.div(4, -9);
  19. System.out.println("x="+x);
  20. System.out.println("over");
  21. }
  22. }

练习:毕老师用电脑上课。
解:
分析:开始思考上课中出现的问题。比如问题是:电脑蓝屏、电脑冒烟。要对问题进行描述,封装成对象。可是当冒烟发生后,出现讲课进度无法继续,出现了讲师的问题,课时计划无法完成。

  1. class LanPingException extends Exception {
  2. LanPingException(String message) {
  3. super(message);
  4. }
  5. }
  6. class MaoYanException extends Exception {
  7. MaoYanException(String message) {
  8. super(message);
  9. }
  10. }
  11. class NoPlanException extends Exception {
  12. NoPlanException(String msg) {
  13. super(msg);
  14. }
  15. }
  16. class Computer {
  17. private int state = 3;
  18. public void run() throws LanPingException, MaoYanException {
  19. if(state == 2)
  20. throw new LanPingException("蓝屏了");
  21. if(state == 3)
  22. throw new MaoYanException("冒烟了");
  23. System.out.println("电脑运行");
  24. }
  25. public void reset() {
  26. state = 1;
  27. System.out.println("电脑重启");
  28. }
  29. }
  30. class Teacher {
  31. private String name;
  32. private Computer cmpt;
  33. Teacher(String name) {
  34. this.name = name;
  35. cmpt = new Computer();
  36. }
  37. public void prelect() throws NoPlanException {
  38. try {
  39. cmpt.run();
  40. } catch(LanPingException e) {
  41. cmpt.reset();
  42. } catch(MaoYanException e) {
  43. test();
  44. throw new NoPlanException("课时无法继续----"+e.getMessage());
  45. }
  46. System.out.println("讲课");
  47. }
  48. public void test() {
  49. System.out.println("练习");
  50. }
  51. }
  52. class ExceptionTest {
  53. public static void main(String[] args) {
  54. Teacher t = new Teacher("毕老师");
  55. try {
  56. t.prelect();
  57. } catch(NoPlanException e) {
  58. System.out.println(e.toString());
  59. System.out.println("换老师,或者放假");
  60. }
  61. }
  62. }

finally代码块

定义一定执行的代码。通常用于关闭资源。
finally使用举例:
例1,

  1. class FuShuException extends Exception {
  2. FuShuException(String msg) {
  3. super(msg);
  4. }
  5. }
  6. class Demo {
  7. int div(int a, int b) throws FuShuException {
  8. if(b < 0)
  9. throw new FuShuException("出现了除数为负");
  10. return a/b;
  11. }
  12. }
  13. class ExceptionDemo {
  14. public static void main(String[] args) {
  15. Demo d = new Demo();
  16. try {
  17. int x = d.div(4, -1);
  18. System.out.println("x="+x);
  19. } catch (FuShuException e) {
  20. System.out.println(e.toString());
  21. return;
  22. } finally {
  23. System.out.println("finally"); // finally中存放的是一定会被执行的代码
  24. }
  25. System.out.println("over");
  26. }
  27. }

例2,操作数据库

  1. class NoException extends Exception {
  2. }
  3. public void method() throws NoException {
  4. 连接数据库;
  5. 数据操作; //throw new SQLException();
  6. 关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。
  7. try {
  8. 连接数据库;
  9. 数据操作; //throw new SQLException();
  10. } catch(SQLException e) {
  11. 会对数据库进行异常处理;
  12. throw new NoException();
  13. } finally {
  14. 关闭数据库;
  15. }
  16. }

记住一点:catch是用于处理异常,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明。

异常在子父类覆盖中的体现

练习:有一个圆形和长方形,它们都可以获取面积,对于面积如果出现非法的数值,视为是获取面积出现问题。问题通过异常来表示。
解:先要对这个程序进行基本设计。

  1. class NoValueException extends RuntimeException {
  2. NoValueException(String message) {
  3. super(message);
  4. }
  5. }
  6. interface Shape {
  7. void getArea();
  8. }
  9. class Rec implements Shape {
  10. private int len, wid;
  11. Rec(int len, int wid) {
  12. if(len <= 0 || wid <= 0)
  13. throw new NoValueException("出现非法值");
  14. this.len = len;
  15. this.wid = wid;
  16. }
  17. public void getArea() {
  18. System.out.println(len*wid);
  19. }
  20. }
  21. class Circle implements Shape {
  22. private int radius;
  23. public static final double PI = 3.14;
  24. Circle(int radius) {
  25. if(radius <= 0)
  26. throw new NoValueException("非法值");
  27. this.radius = radius;
  28. }
  29. public void getArea() {
  30. System.out.println(radius*radius*PI);
  31. }
  32. }
  33. class ExceptionTest {
  34. public static void main(String[] args) {
  35. Rec r = new Rec(3, 4);
  36. r.getArea();
  37. Circle c = new Circle(-8);
  38. System.out.println("over");
  39. }
  40. }

总结

异常:对问题的描述,将问题进行对象的封装。


异常体系:

Throwable
   |---Error
   |---Exception
           |---RuntimeException

异常体系的特点:异常体系中的所有类以及建立的对象都具有可抛性,也就是说可以被throwthrows关键字所操作。只有异常体系具备这个特点。


throwthrows的用法:

当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,否则编译失败。
注意:RuntimeException除外,也就是说,函数内如果抛出的是RuntimeException异常,函数上可以不用声明。


如果函数声明了异常,调用者需要进行处理,处理方式可以throws也可以try
异常有两种:


异常处理语句:

  1. try {
  2. 需要被检测的代码;
  3. } catch() {
  4. 处理异常的代码;
  5. } finally {
  6. 一定会指执行的代码;
  7. }

有三种结合格式:

    1.
  1. try {
  2. 需要被检测的代码;
  3. } catch() {
  4. 处理异常的代码;
  5. }
    2.
  1. try {
  2. 需要被检测的代码;
  3. } finally {
  4. 一定会指执行的代码;
  5. }
    3.
  1. try {
  2. 需要被检测的代码;
  3. } catch() {
  4. 处理异常的代码;
  5. } finally {
  6. 一定会指执行的代码;
  7. }

注意:


自定义异常:定义类继承Exception或者RuntimeException

  1. 为了让自定义类具备可抛性
  2. 让该类具备操作异常的共性方法

当要定义自定义异常的信息时,可以使用父类已经定义好的功能。将异常信息传递给父类的构造函数。

  1. class MyException extends Exception {
  2. MyException(String message) {
  3. super(message);
  4. }
  5. }

自定义异常:按照java的面向对象思想,将程序出现的特有问题进行封装。


异常的好处:

  1. 将问题进行封装
  2. 将正常流程代码和问题处理代码相分离,方便于阅读

异常的处理原则:

  1. 处理方式有两种:try或者throws
  2. 调用到抛出异常的功能时,抛出几个,就处理几个。一个try对应多个catch
  3. 多个catch,父类的catch放到最下面
  4. catch内,需要定义针对性的处理方式,不要简单的定义printStackTrace或者输出语句。也不要不写

当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。

  1. try{
  2. throw new AException();
  3. } catch(AException e) {
  4. throw e;
  5. }

如果该异常处理不了,但并不属于该功能出现的异常。可以将异常转换后,在抛出和该功能相关的异常。

  1. try{
  2. throw new AException();
  3. } catch(AException e) {
  4. throw new BException();
  5. }

或者异常可以处理,但需要将异常产生后,和本功能相关的问题提供出去,让调用者知道并处理,即将捕获异常处理后,转换新的异常抛出。(比如,汇款的例子)

  1. try{
  2. throw new AException();
  3. } catch(AException e) {
  4. AException处理
  5. throw new BException();
  6. }

异常的注意事项:
在子父类覆盖时

  1. 子类抛出的异常必须是父类的异常的子类或者子集
  2. 如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛

包(package)

总结:

四种访问权限

public protected default private
同一类中
同一包中
子类
不同包中

import

为了简化类名的书写,使用一个关键字——import
import导入的是包中的类,不导入包中的包。
建议:

例,

  1. package pack;
  2. import packb.haha.hehe.heihei.*;
  3. import packa.*;
  4. class PackageDemo {
  5. public static void main(String[] args) {
  6. DemoC c = new DemoC();
  7. }
  8. }

Jar包

Java的压缩包

Jar包的操作
通过jar.exe工具对jar的操作。

jar包中的内容很多,在dos命令行环境中一屏显示不过来,可用如下命令:

C:\myclass>jar -tf yelei.jar >c:\1.txt

即将yelei.jar包中的内容存放到c盘下1.txt文本文档中。
数据重定向——数据不想在一个地方(例如dos命令行)显示,而想在文件中显示。可用如下命令:

C:\>dir >c:\2.txt

即将c盘目录下的文件信息存放在c盘下2.txt文本文档中。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注