Java学习日记(六)异常、包

一、异常

先看一个示例:

class Demo {
       int div(int a, int b) {
              return a / b;
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Demo d = new Demo();
              int x = d.div(4, 1);
              System.out.println(x);
              int y = d.div(4, 0);
              System.out.println(y);          
              System.out.println("over");
       }
}

运行结果为:

4

Exceptionin thread "main" java.lang.ArithmeticException: / by zero

    at Demo.div(ExceptionDemo.java:14)

    at ExceptionDemo.main(ExceptionDemo.java:6)

附注:当程序运行出现异常后,出现异常位置后的代码就不再运行

1.概念:就是程序在运行时出现的不正常情况

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

3.异常的体系:

       Throwable

              ·Error

                     ----通常出现重大问题如:运行的类不存在或者内存溢出等

                     ----不编写针对代码对其处理

              ·Exception

                     ----在运行时运行出现的一起情况,可以通过针对性的处理方式进行处理

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

Exception和Error的子类名都是以父类名作为后缀

4.异常的处理格式:

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

try{

       需要被检测的代码;

}catch(异常类变量){

       处理异常的代码;(处理方式)

}finally{

       一定会执行的语句;

}

针对上面除法出现的异常,我们给出相应的解决方式:

class Demo {
       //在功能上通过throws的关键字声明了该功能有可能会出现问题。
       int div(int a, int b)throws Exception {
              return a / b;
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Demo d = new Demo();
              try{
                     int x = d.div(4, 1);
                     System.out.println(x);
                     int y = d.div(4, 0);
                     System.out.println(y);
                     System.out.println("over1");
              }catch (Exception e) {
                     System.out.println("除0了");
                     //获取错误信息
                     System.out.println(e.getMessage());
                     //异常名称和异常信息
                     System.out.println(e.toString());
                     //异常名称,异常信息和异常出现的位置。jvm默认调用就是printStackTrace()
                     e.printStackTrace();
              }
              System.out.println("over2");
       }
}

运行结果:

4

0

/ by zero

java.lang.ArithmeticException: / by zero

java.lang.ArithmeticException: / by zero

    at Demo.div(ExceptionDemo.java:26)

    at ExceptionDemo.main(ExceptionDemo.java:7)

over2

总结:当程序运行出现异常后,出现异常位置后的代码就不再运行,在函数上声明异常,便于提高安全性,让调用者进行处理。

5.Throwable中的方法

       ·getMessage()----获取异常信息,返回字符串

       ·toString()----获取类名和异常信息,返回字符串

       ·printStackTrace()----获取类名和异常信息,以及异常出现在程序中的位置,返回值void

       ·printStackTrace(PringStrean s)----通常用该方法将异常内容保存在日志文件中,以便查阅

6.对异常的处理:

★声明异常时,建议声明更为具体的异常。这样处理的可以更具体。

★对方声明几个异常,就对应有几个catch块,不要定义多余的catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

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

示例:

class Demo {
       //在功能上通过throws的关键字声明了该功能有可能会出现问题。
       void div(int a, int b) throws ArithmeticException,
                     ArrayIndexOutOfBoundsException{
              System.out.println(a/ b);
              int[] arr = new int[a];
              System.out.println(arr[4]);
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Demo d = new Demo();
              try{
                     d.div(6,2);
                     System.out.println("-------");
                     //被零除了!!
                     d.div(5,0);
                     System.out.println("-------");
                     //角标越界啦!!
                     d.div(4,2);
              }catch (ArithmeticException e) {
                     System.out.println(e.toString());
                     System.out.println("被零除了!!");
              }catch (ArrayIndexOutOfBoundsException e) {
                     System.out.println(e.toString());
                     System.out.println("角标越界啦!!");
              }catch (Exception e) {
                     System.out.println("hahah:"+ e.toString());
              }
              System.out.println("over");
       }
}

运行结果:

3

0

-------

java.lang.ArithmeticException: / by zero

被零除了!!

over

7.自定义异常:

因为项目中会出现特有的问题,而这些问题并未被java所描述并封装,所以对于这些特有的问题可以按照java对问题封装的思想将特有问题进行自定义的异常封装。

当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作,要么在内部try…catch处理,要么在函数上声明让调用者处理

一般情况下,函数内出现异常,函数上需要声明

如果发现打印的结果中只有异常的名称,却没有异常的信息,是因为自定义的异常并为定义信息。

那么如何定义异常信息呢?

因为父类中已经把异常信息的操作都完成了,所以子类只要在构造时,将异常信息传递给父类通过super语句,那么就可以直接通过getMessage()方法获取自定义的异常信息了。

自定义类继承Exception或者其子类

继承Exceprion的原因:

异常体系有一个特点:因为异常类和异常对象都被抛出。他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。只有这个体系中的类和对象才可以被throws和throw操作。

通过构造函数定义异常信息

throws和throw

              throws用于标识函数暴露出的异常

              throw用于抛出异常

       throws和throw的区别:

              throws用在函数上,后面跟异常类名

              throw用在函数内,后面跟异常对象

示例:(对于除数是-1,也视为是错误的是无法进行运算的)

class FuShuException extends Exception{
       private int value;
       FuShuException(){
              super();
       }
       FuShuException(String msg,int value){
              super(msg);
              this.value=value;
       }
       public int getValue(){
              return value;
       }
}

class Demo{
       int div(int a,int b)throws FuShuException{
              if(b<0)
                     //手动通过throw关键字抛出一个自定义异常对象
                     throw new FuShuException(“出现了除数是负数的情况----/by fushu”,b);
              return a/b;
       }
}

class ExceptionDemo{
       public static void main(String[] args){
              Demo d=new Demo();
              try{
                     int x=d.div(4,-9);
                     System.out.println(x);
              }catch(FuShuExceptione){
                     System.out.println(e.toString());
                     System.out.println(“错误的负数是:”+e.getValue());
              }
              System.out.println(“over”);
       }
}

运行结果是:

FuShuException:出现了除数是负数的情况----/by fushu

错误的负数是:-9

over

8.RuntimeException讲解:

Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常,如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过;如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过。之所以不用在函数声明,是因为不需要让调用者处理。当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

注意:

异常细节:自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException

异常分两种:

1.编译时被检测的异常;2.编译时不被检测的异常(运行时异常,RuntimeException以及其子类)

示例:

class FuShuException extendsRuntimeException {
       FuShuException(String msg) {
              super(msg);
       }
}

class Demo {
       int div(int a, int b) throws ArithmeticException {
              if(b < 0)
                     throw new ArithmeticException("出现了除数为负数了");
              if(b == 0)
                     throw new ArithmeticException("被零除啦");
              return a / b;
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Demo d = new Demo();
              int x = d.div(4, 2);
              System.out.println("x="+ x);
              int y = d.div(4, -2);
              System.out.println("y="+ y);
              System.out.println("over");
       }
}

运行结果:

x=2

Exceptionin thread "main" java.lang.ArithmeticException:出现了除数为负数了

    at Demo.div(ExceptionDemo.java:20)

    at ExceptionDemo.main(ExceptionDemo.java:6)

总结:

·RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明

·一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类

·如果父类抛出多个异常的一个子集,不能抛出新的异常

·介绍异常在分层设计时的层内封装

练习:(自定义异常,对上课可能出现的意外情况进行处理)

假设问题有:电脑蓝屏、电脑冒烟(要对问题进行描述,封装成类),当出现不同的问题,要进行相应的处理

代码实现如下:

class LanPingException extends Exception {
       LanPingException(String msg) {
              super(msg);
       }
}

class MaoYanException extends Exception {
       MaoYanException(String msg) {
              super(msg);
       }
}

class NoPlanException extends Exception {
       NoPlanException(String msg) {
              super(msg);
       }
}

class Computer {
       private int state = 3;
       public void run() throws LanPingException, MaoYanException {
              if(state == 2)
                     throw new LanPingException("蓝屏了");
              if(state == 3)
                     throw new MaoYanException("冒烟了");
              System.out.println("电脑运行");
       }
       public void reset() {
              state= 1;
              System.out.println("电脑重启");
       }
}

class Teacher {
       private String name;
       private Computer cmpt;
       Teacher(String name) {
              this.name= name;
              cmpt= new Computer();
       }
       public void prelect() throws NoPlanException {
              try{
                     cmpt.run();
              } catch (LanPingException e) {
                     System.out.println(e.getMessage());
                     cmpt.reset();
              }catch (MaoYanException e) {
                     thrownew NoPlanException("课时无法继续.." + e.getMessage()+"..."+this.test());
              }
              System.out.println("继续讲课");
       }
       publicString test() {
              return"学生自己练习";
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Teachert = new Teacher("王老师");
              try{
                     t.prelect();
              }catch (NoPlanException e) {
                     System.out.println(e.toString());
              }
       }
}

运行结果:

NoPlanException:课时无法继续..冒烟了...学生自己练习

9. finally代码块

定义一定执行的代码,通常用于关闭资源。(比如数据库的关闭,流的关闭等等)

示例:

class FuShuException extends Exception {
       FuShuException(String msg) {
              super(msg);
       }
}

class Demo {
       int div(int a, int b) throws FuShuException {
              if(b < 0)
                     throw new FuShuException("除数为负数");
              returna / b;
       }
}

class ExceptionDemo {
       public static void main(String[] args) {
              Demo d = new Demo();
              try{
                     int x = d.div(4, -1);
                     System.out.println("x="+ x);
              }catch (FuShuException e) {
                     System.out.println(e.toString());
                     return;
                     //System.exit(0);//系统,退出。jvm结束。
              }finally {
                     System.out.println("finally");//finally中存放的是一定会被执行的代码。
              }
              System.out.println("over");
       }
}

运行结果:

FuShuException:除数为负数

finally

总结:

System.exit(0);语句打开后,系统就会退出,jvm结束,finally语句不会执行。

return语句关闭后,System.out.println("over");也会执行。

示例2:(关于数据库的使用)

class NoException extends Exception{
}

处理数据库的方法:
public void method()throws NoException{
       //连接数据库;
       //数据操作;//throw new SQLException();
       //关闭数据库;//该动作,无论数据操作是否成功,一定要关闭资源。
       try{
              连接数据库;
              数据操作;//throw new SQLException();
       }catch(SQLException e){
              会对数据库进行异常处理;
              throw new NoException();
       }finally{
              关闭数据库;
       }
}


10.try、catch、finally的组合形式

第一种格式:

try{

 

}catch(){

 

}

第二种格式:

try{

 

}catch(){

 

}finally{

 

}

第三种格式:

try{

 

}finally{

 

}

附注:catch是用于处理异常,如果没有catch就代表异常没有被处理过,如果该异常是检测时异常,那么必须声明.

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

⑴子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类

⑵如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

⑶如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。如果子类方法发生了异常,就必须要进行try处理,绝对不能抛。

示例:

class AException extends Exception {}

class BException extends AException {}

class CException extends Exception {}

class Fu {
       void show() throws AException, CException {}
}

class Zi extends Fu {
       //子类覆盖父类方法时,抛出父类的异常或者该异常的子类
       void show() throws AException, BException, CException {}
}

class Test {
       voidfunction(Fu f) {
                     try{
                            f.show();
                     }catch (AException | CException e) {
                            e.printStackTrace();
                     }    
       }
}

练习:(有一个圆形和长方形,都可以获取面积,对于面积如果出现非法的数值,视为是获取面积出现问题,问题通过异常来表示)

代码如下:

interface Shape {
       void getArea();
}

class NoValueException extendsRuntimeException {
       NoValueException(String message) {
              super(message);
       }
}

class Rec implements Shape {
       private int len, wid;
       Rec(int len, int wid){
              if(len <= 0 || wid <= 0)
                     throw new NoValueException("长方形出现非法值");
              this.len= len;
              this.wid= wid;
       }
       public void getArea() {
              System.out.println(len* wid);
       }
}

class Circle implements Shape {
       private int radius;
       public static final double PI = 3.14;
       Circle(intradius) {
              if(radius <= 0)
                     throw new NoValueException("圆形半径非法");
              this.radius= radius;
       }
       public void getArea() {
              System.out.println(radius* radius * PI);
       }
}
class ExceptionDemo {
       public static void main(String[] args) {
              Recr1 = new Rec(3, 4);
              r1.getArea();
              Circlec1 = new Circle(4);
              c1.getArea();
              System.out.println("-------");
              Recr2 = new Rec(3, -4);
              r2.getArea();
              Circlec2 = new Circle(-4);
              c2.getArea();
       }
}

运行结果:

12

50.24

-------

Exceptionin thread "main" NoValueException:长方形出现非法值

    at Rec.<init>(ExceptionDemo.java:27)

    at ExceptionDemo.main(ExceptionDemo.java:8)

 

二、包(package)

1.特点:

·对类文件进行分类管理

·给类提供多层命名空间

·卸载程序文件的第一行

·类名的全名是 包名.类名

·包也是一种封装形式

2.包之间的访问:

·被访问的包中类的权限必须是public的

·类中的成员权限:public或者protected

·protected是为其他包中的子类提供一种权限

3.四种权限:


import作用:

·简化包名

·一个程序文件中只有一个package,可以有多个import

·用来导入包中的类,不导入包中的包

·通常写importmypack.Demo(如果写importmypack.*的话,jvm会依次寻找,降低运行速度)

附注:(常用包)

java.lang: java的核心包 jdk1.2版本以后,该包中的类自动导入。

java.awt:用于制作图形界面。

java.io:用于操作设备上的数据。

java.util:这里定义是java的工具类。(集合,日期……)

java.net:用于网络通讯的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值