《day12---异常》

 1 //91-面向对象-异常-异常的发生和简单应用。
 2 /*
 3 异常:
 4 java运行时期发生的问题就是异常。
 5 
 6 Java中运行时的除了异常Exception含有错误Error.
 7 
 8 异常:通常发生后可以有针对性的处理方式的。
 9 错误:通常发生后不会有针对性的处理方式。
10       Error的发生往往都是系统级别的问题,都是jvm所在系统发生的并反馈给jvm
11       无法修正处理,只能修改源代码。
12 */
13 
14 class ExceptionDemo 
15 {
16     public static void main(String[] args) 
17     {
18         int[] arr = new int[1024*1024*1000];//Exception in thread "main" java.lang.OutOfMemoryError:
19         System.out.println(arr[0]);
20         System.out.println(arr[3]);//改句运行时,发生了异常Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3
21                                     //导致程序无法执行,程序结束。
22         System.out.println("over");
23     }
24 }
 1 //92-面向对象-异常-异常的发生和简单应用。
 2 class Person
 3 {
 4     private String name;
 5     private int age;
 6     Person(String name,int age)
 7     {
 8         //加入逻辑判断。
 9         if(age<0 || age>200)
10         {
11             /*
12             这样做虽然可以编译运行看到提示消息,但是问题却没有发生,
13             程序还在继续执行,并打印了p对象,这是不合理的,人对象初始化过程
14             中已经出了问题,为什么还要对人对象进行操作。
15             所以应该将问题暴露出来,让使用改程序的调用者知道,
16             所以要用异常来解决。
17             */
18 //            System.out.println("年龄数值错误");
19 //            return;//终止初始化。
20             throw new IllegalArgumentException(age+",年龄数值非法");
21         }
22         this.name = name;
23         this.age = age;
24     }
25     //定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
26     public String toString()
27     {
28         return "Person[name="+name+",age="+age+"]";
29     }
30 }
31 
32 
33 class ExceptionDemo2 
34 {
35     public static void main(String[] args) 
36     {
37         Person p = new Person("XiaoMing",-20);
38         System.out.println(p);
39 
40     }
41 }
  1 //93-异常的定义&体系。
  2 /*
  3 ExceptionDemo2.java中的异常不好认,能不能定义一个符合我的程序要求的问题。
  4 
  5 异常的信息都可以自己定义,那么异常的名字是否可以自己定义呢?是否可以更
  6 符合自己程序的阅读呢?
  7 
  8 之前的几个异常都是java通过类进行描述,并将问题封装成对象,这是符合面向对象的
  9 思想的。
 10 其实:异常就是讲问题封装成了对象。
 11 
 12 所以我也准备对自己所需要的问题进行类的描述。
 13 
 14 发生了编译失败:
 15 ExceptionDemo3.java:43: 错误: 不兼容的类型: NoAgeException无法转换为Throwable
 16                         throw new NoAgeException(age+",年龄数值非法");
 17                         ^
 18 1 个错误
 19 
 20 不兼容,不明白,查阅API文档,提示说无法转换为Throwable,啥东西?
 21 搜索API,看到Throwable描述,发现,它是异常和错误的超类。
 22 原来它是异常体系的顶层类。
 23 Throwable
 24     |--Error
 25     |--Excepton.
 26 
 27 通过阅读,自定义异常被抛出,必须是继承Throwable,或者继承Throwable的子类
 28 该对象才可以被throw抛出。
 29 
 30 原来这个异常体系局部一个特有的特性,可抛性,可以被throw关键字操作。
 31 
 32 继承选择父类时,更为确切的是继承Exception。
 33 但是发现编译又异常失败了。
 34 
 35 ExceptionDemo3.java:61: 错误: 未报告的异常错误NoAgeException; 必须对其进行捕获或声明 以便抛出
 36                         throw new NoAgeException(age+",年龄数值非法");
 37                         ^
 38 1 个错误
 39 
 40 通过这个编译失败提示,发现自定义的异常和之前所使用的异常(空指针异常,
 41 角标越界异常,无效参数异常有不同。)
 42 抛出那些异常没有这个失败提示,那么之前的异常和自定义的异常有什么区别呢?
 43 通过查看API文档的继承体系发现,之前的异常都是Exception下面的RuntimeException子类
 44 的子类。
 45 阅读RuntimeException描述中有明确说明,这个运行时异常以及其子类都无需进行声明。
 46 
 47 可以将自定义的异常继承RuntimeException。
 48 
 49 */
 50 
 51 //自定义异常。描述Person的年龄数值非法。
 52 /**
 53 只要是本项目中的Person的年龄出现非法值,就会发生该异常。
 54 */
 55 class NoAgeException extends RuntimeException
 56 {
 57     /*
 58     为什么要定义构造函数,因为看到java中的异常描述类中有提供对问题的构造方法。
 59     */
 60     NoAgeException()
 61     {
 62         super();
 63     }
 64 
 65     NoAgeException(String message)
 66     {
 67         super(message);//如果自定义异常需要异常信息,可以通过调用父类带有
 68                         //字符串参数的构造函数即可。
 69     }
 70 }
 71 
 72 class Person
 73 {
 74     private String name;
 75     private int age;
 76     Person(String name,int age)
 77     {
 78         //加入逻辑判断。
 79         if(age<0 || age>200)
 80         {
 81             throw new NoAgeException(age+",年龄数值非法");
 82         }
 83         this.name = name;
 84         this.age = age;
 85     }
 86     //定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
 87     public String toString()
 88     {
 89         return "Person[name="+name+",age="+age+"]";
 90     }
 91 }
 92 
 93 
 94 class ExceptionDemo3
 95 {
 96     public static void main(String[] args) 
 97     {
 98         Person p = new Person("XiaoMing",-20);
 99         System.out.println(p);
100 
101     }
102 }
 1 //94-编译时异常和运行时异常
 2 /*
 3 ExceptionDemo3.java中涉及的问题。
 4 1,继承Exception和继承RuntimeException为什么差距那么大?
 5 2,啥是捕获,啥事声明?
 6 */
 7 
 8 class Demo
 9 {
10     void show()
11     {
12         //如果在函数内抛出Exception//编译失败,因为编译器在检查语法时发生了错误。
13         /*
14         该抽象已经出现问题,java认为这个程序本身存在隐患,需要捕获或者声明出来。
15         (要么捕获,要么声明出来,让调用者知道。)
16         */
17 //        throw new Exception();
18 
19         /*
20         为什么抛出RuntimeException就不需要捕获,不需要声明呢?
21         不是功能本身发生的异常,而是因为比如调用者传递参数错误
22         而导致功能运行失败。
23         这时也是问题,需要通过异常来体现,但是这个异常时不需要声明
24         出来的。
25         声明的目的是为了让调用者进行处理。
26         不声明的目的是不让调用者进行处理。就是为了让程序停止,让调用
27         者看到现象,并进行代码的修正。☆☆☆☆☆
28 
29 
30         异常分两种
31         1.编译时异常。编译器会检测。
32         2.运行时异常。编译器不会检测,不需要声明。声明也可以,如果声明了
33                                         无外乎,就是让调用者给出处理方式。
34         常见的异常;
35         ArrayIndexOutOfBoundsEception
36         IllegalArgumentException
37         NullPointerException
38         ClassCastException
39 
40         */
41         throw new RuntimeException();
42     }
43 }
44 class ExceptionDemo4
45 {
46     public static void main(String[] args) 
47     {
48         System.out.println("Hello World!");
49     }
50 }
 1 //95-异常-声明&捕获
 2 /*
 3 声明和捕获:
 4 声明:将问题标识出来,报告给调用者。
 5 如果函数内,通过throw抛出了编译时异常,而没有捕获,
 6 那么必须通过throws进行声明,让调用者去处理。
 7 
 8 捕获:java中对异常有针对性的语句进行捕获。
 9 语句:
10 try
11 {
12     //需要被检测的代码或者语句。
13 }
14 catch(异常类 变量)//参数。
15 {
16     //异常的处理语句。
17 }
18 finally
19 {
20     //一定会被执行的语句。
21 }
22 
23 */
24 class Demo
25 {
26     /*
27     如果定义功能时,有问题发生,需要报告给调用者,可以在函数
28     上使用throws进行声明。
29     */
30     void show(int x)throws Exception
31     {
32         if(x>0)
33         throw new Exception();
34         else
35             System.out.println("show run");
36     }
37 }
38 
39 class ExceptionDemo5
40 {
41     public static void main(String[] args)//throws Exception//在调用者上继续声明
42     {
43         Demo d = new Demo();
44         try
45         {
46             d.show(2);//当调用了声明异常的方法时,必须有处理方式,要么捕获,要么声明。
47         }
48         catch (Exception ex)//括号中,需要定义什么呢?对方抛出的是什么问题,在括号中就定义什么问题的引用。
49         {
50             System.out.println("异常发生了");
51         }
52         
53         System.out.println("Hello World!");
54     }
55 }
 1 //96-声明&捕获在例子中的应用。
 2 
 3 class NoAgeException extends RuntimeException
 4 {
 5     /*
 6     为什么要定义构造函数,因为看到java中的异常描述类中有提供对问题的构造方法。
 7     */
 8     NoAgeException()
 9     {
10         super();
11     }
12 
13     NoAgeException(String message)
14     {
15         super(message);//如果自定义异常需要异常信息,可以通过调用父类带有
16                         //字符串参数的构造函数即可。
17     }
18 }
19 
20 class Person
21 {
22     private String name;
23     private int age;
24 
25     /*
26     构造函数到底抛出的NogAgeException是继承Exception呢?还是继承
27     RuntimeException呢?
28     继承Exception就必须要throws声明,一旦声明就告知调用者要进行捕获,
29     一旦问题处理完了,调用者的程序会继续执行,但是,如果使用到了Person
30     对象的数据,会导致代码都是失败的。
31     如果继承RuntimeException是不需要throws声明的,那么这时,调用者是不可
32     能编写捕获代码的,因为调用者根本不知道有问题。
33     一旦发生NoAgeExcepton,调用者程序会停掉,并由jvm将信息显示到屏幕上。
34     让调用者看到,然后调用者去修改源代码。
35     */
36     Person(String name,int age)//throws NoAgeException
37     {
38         //加入逻辑判断。
39         if(age<0 || age>200)
40         {
41             throw new NoAgeException(age+",年龄数值非法");
42         }
43         this.name = name;
44         this.age = age;
45     }
46     //定义Perosn对象对应的字符串表现形式,覆盖Object中的toString方法,
47     public String toString()
48     {
49         return "Person[name="+name+",age="+age+"]";
50     }
51 }
52 
53 class ExceptionDemo6
54 {
55     public static void main(String[] args) 
56     {
57 //        try
58 //        {
59             Person p = new Person("XiaoMing",20);
60             System.out.println(p);
61 //        }
62 //        catch (NoAgeException ex)
63 //        {
64     //        System.out.println("异常发生了");
65 //        }
66     
67         System.out.println("over");
68 
69     }
70 }
 1 //97-运行时异常的应用。
 2 /*
 3 描述长方形:
 4     属性:长和宽。
 5     行为:获取面积。
 6 
 7 考虑健壮性问题:
 8 万一长和宽数值非法。
 9 描述问题:将问题封装成对象,用异常的方式来表示。
10 */
11 
12 /*
13 不知道要继承编译时异常还是运行时异常。
14 */
15 
16 class NoValueException extends RuntimeException
17 {
18     NoValueException()
19     {
20         super();
21     }
22     NoValueException(String message)
23     {
24         super(message);
25     }
26 }
27 class Rec
28 {
29     private int length;
30     private int width;
31     Rec(int length,int width)
32     {
33         if(length<=0 || width<=0)
34         {
35             //抛出异常,但是不用声明,不需要调用者处理,就需要一旦问题日发生,让调用者端进行停止,修改代码去。
36             throw new NoValueException("长或者宽的数值非法,请修正。");
37         }
38         this.length = length;
39         this.width = width;
40     }
41     /**
42     定义面积函数。
43     */
44     public int getArea()
45     {
46         return length*width;
47     }
48 }
49 class ExceptionDemo7
50 {
51     public static void main(String[] args) 
52     {
53         Rec r = new Rec(-3,4);
54         int area = r.getArea();
55         System.out.println("area="+area);
56 
57     }
58 }
  1 //98-99--编译时异常和异常的转换
  2 /*
  3 案例二:毕老师用电脑讲课。
  4 两个对象:
  5     老师:
  6         属性:姓名。
  7         行为:讲课。
  8     电脑:
  9         行为:运行。
 10 
 11 考虑问题:
 12 1.电脑蓝屏--->异常
 13 
 14 2.电脑冒烟了-->异常
 15 */
 16 //可以声明出来,让调用者给出处理方式。
 17 class LanPingException extends Exception
 18 {
 19     LanPingException()
 20     {
 21         super();
 22     }
 23     LanPingException(String message)
 24     {
 25         super(message);
 26     }
 27 }
 28 
 29 class MaoYanException extends Exception
 30 {
 31     MaoYanException()
 32     {
 33         super();
 34     }
 35     MaoYanException(String message)
 36     {
 37         super(message);
 38     }
 39 }
 40 /*
 41 讲课中冒烟,问题可以临时解决,但是冒烟问题没有直接处理,所以就使用throws声明。
 42 但是发现,这个问题不应该属于讲课的问题,调用讲课方法的调用者处理不了这个问题,
 43 该调用者能处理的应该是冒烟导致的课程进行不下去的问题。
 44 应该在列出一个异常,课时停止异常。
 45 */
 46 
 47 class NoPlanException extends Exception
 48 {
 49     NoPlanException()
 50     {
 51         super();
 52     }
 53     NoPlanException(String message)
 54     {
 55         super(message);
 56     }
 57 }
 58 
 59 class NoteBook
 60 {
 61     private int state=2;
 62     public void run()throws LanPingException,MaoYanException
 63     {
 64         System.out.println("笔记本电脑运行");
 65         if(state == 1)
 66             throw new LanPingException("电脑蓝屏了");
 67         if(state == 2)
 68             throw new MaoYanException("电脑冒烟了");
 69     
 70     }
 71     public void reset()
 72     {
 73         state = 0;
 74         System.out.println("电脑重启");
 75     }
 76 }
 77 
 78 class Teacher
 79 {
 80     private String name;
 81     private NoteBook book;
 82     Teacher(String name)
 83     {
 84         this.name = name;
 85         book = new NoteBook();
 86     }
 87 
 88     //讲课:
 89     public void prelect()throws NoPlanException
 90     {
 91         /*
 92         调用到了声明异常的方法,在这里到底是捕获好呢?还是声明好呢?
 93         有具体的捕获处理方法吗?有,那就捕获,没有,那就声明。
 94         我可以处理,重启电脑就可以了,重启是电脑的功能。
 95         */
 96         try
 97         {
 98             book.run();//对于声明多个异常的方法,在处理,需要定义多个catch与之对应。
 99         }
100         catch (LanPingException e)//LanPingException e = new LnaPingException("电脑蓝屏了")
101         {
102             //重启;
103             System.out.println(e.toString());
104             e.printStackTrace();
105             book.reset();
106         }
107         catch(MaoYanException e)//MaoYanException e = MaoYanException("电脑冒烟了");
108         {
109             System.out.println(e.toString());
110             test();
111             //冒烟问题没有解决。继续声明throws出去。
112 //            throw e;
113             throw new NoPlanException(e.getMessage()+",课时停止");//异常转换。
114 
115         }
116         System.out.println("讲课");
117     }
118         //留练习题
119         public void test()
120         {
121         System.out.println("做练习");
122         }
123 }
124 
125 class ExceptionDemo8 
126 {
127     public static void main(String[] args) 
128     {
129         Teacher t = new Teacher("毕老师");
130         try
131         {    
132             t.prelect();
133         }
134         catch (NoPlanException e)
135         {
136             System.out.println(e.toString());
137             System.out.println("换老师");
138         }
139         System.out.println("Hello World!");
140     }
141 }
 1 //100-throw和throws的区别。
 2 /*
 3 throw和throws的区别:
 4  
 5  1,throw用在函数内,
 6    throws用在函数上。
 7  2,throw抛出的是异常对象。
 8     throws用于进行异常类的声明,后面异常类用逗号隔开。
 9 */
10 class Demo
11 {
12     void show()throw Exception
13     {
14         throw new Exception();
15     }
16 }
17 class  
18 {
19     public static void main(String[] args) 
20     {
21         System.out.println("Hello World!");
22     }
23 }
原文地址:https://www.cnblogs.com/sun-/p/5374671.html