关闭

黑马程序员——异常和包

85人阅读 评论(0) 收藏 举报
黑马程序员--异常和包

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

异常

一、定义

异常:程序运行时出现的不正常情况。
异常由来:Java运用面对对象思想,将程序运行的不正常情况进行描述、封装后,形成的对象。
异常的运用,提高了代码安全性

二、特点

1、将正常流程代码和问题处理代码分离,提高阅读性;
2、不同问题用不同的类进行具体描述。如:角标越界、空指针异常等。
3、根据不同的问题分类,建立异常体系。应用原则:看父类定义,建立子类对象。
4、将可抛问题划分为:
a、严重问题,通过Error类进行描述。Error类一般不编写针对性的代码对其进行处理。
b、非严重问题,通过Exception类进行描述。Exception类对其进行针对性的处理。
Throwable
|--Error
|--Exception
可抛性:指所有可以通过关键字:throws和throw操作的类和对象都具有的属性。

PS:
Throwable中的方法:
getMessage():获取异常信息,返回String;
toString():异常名称和异常信息,返回String;
printStackTrace():获取异常名称、信息和出现的位置。它是jvm默认方法。
printStackTrace(PrintStream s):通常用该方法将异常内容保存在日志文件中,以便查阅。

三、自定义异常

自定义异常:指将自己操作时所特有的异常进行封装的过程。
特点:
1、必须继承异常体系,才能被关键字throws和throw所操作。
自定义类继承Exception或其子类,通过构造函数定义异常信息

  1. Class DemoException extendss Exception  
  2. {  
  3.     DemoException(String msg)  
  4.     {  
  5.         super(msg);  
  6.     }  
  7. }  
2、通过throw将自定义异常抛出。注意:throw和return一样,它后面的语句执行不到。
throws和throw的区别:
a、位置不同:throws使用在函数上;throw使用在函数内。
b、使用格式不同:throws后跟异常类,可以跟多个,用逗号隔开;throw后跟异常对象。

四、异常的分类

1、编译时不被检测的异常(运行时异常):指Exception中的RuntimeException以及其子类
RuntimeException:值在处理影响根本计算的传入值错误,而非程序错误时,编译时不声明错误,直接运行停止,迫使调用者更改。
特点:
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过;
如果在函数上声明类该异常,调用者可以不用进行处理。
用法:当异常的发生可能造成运算无法继续时,让自定义异常继承RuntimeException。

  1. /* 
  2. RuntimeException:运行时异常。它是Exception中一个特殊的子类异常。 
  3. 它用于处理影响根本计算的传入值错误,编译时不声明错误,直接运行停止,迫使调用者更改。 
  4. */  
  5. //自定义异常要继承异常体系   
  6. class FuShuException extends RuntimeException  
  7. {  
  8.     //调用父类功能,接收自定义信息   
  9.     FuShuException(String msg)  
  10.     {  
  11.         super(msg);  
  12.     }  
  13. }  
  14.   
  15. class Demo   
  16. {  
  17.     //因为是运行时异常,不用进行throws NoValueException处理  
  18.     int div(int a,int b)  
  19.     {  
  20.         if(b<0)  
  21.             throw new FuShuException("出现类除数为负数的情形");  
  22.         if(b==0)  
  23.             throw  new ArithmeticException("除数为零");  
  24.         return a/b;  
  25.     }  
  26. }  
  27.   
  28. class ExceptionDemo  
  29. {  
  30.     public static void main(String[] args)  
  31.     {  
  32.         //因为是运行时异常,不用进行try/catch操作   
  33.         Demo d = new Demo();  
  34.         //传入错误数据   
  35.         int x = d.div(4,-5);  
  36.         System.out.println("x="+x);  
  37.     }  
  38. }  
输出结果:

2、编译时被检测的异常。Exception中除RuntimeException之外的异常。这种异常是可处理的,需要调用者进行修复。

五、对多异常的处理:

1、捕捉方式

格式1:
try{
//需要被检测异常的代码
}
catch(异常类 变量){//该变量用于接收发生的异常对象
//处理异常的代码
}
finally{
//一定会执行的代码,通常用于关闭资源。
}

格式2:
try{} catch(){}

格式3:
try{} finally{}

finally代码块:在异常中定义一定执行的代码。

作用:通常用于关闭资源。
异常中,问题可以在内部解决,就可以不在函数上抛出异常。什么叫问题解决?答:有catch就代表问题解决。
注意:catch用于处理异常。没有catch就代表异常没有被处理;如果该异常是检测时异常,则必须声明。
2、抛出
在类中不做处理,由throws抛出,让虚拟机处理。
3、处理原则
a、声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
b、对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
c、函数内容如果抛出需要检测的异常,要么在函数上声明,要么在函数内用try/catch捕捉。
d、如果调用到声明异常的函数,要么try/catch,要么throws。
e、如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

PS:
1、finally代码块只有一种情况不会执行。就是在其前执行了System.exit(0);
2、try是一个独立代码块,其内定义的变量只作用于内部。
3、建立在进行catch处理时,catch中一定要定义具体处理方式。
不要简单定义一句 e.printStackTrace(),
也不要简单的就书写一条输出语句。问题处理方法:异常日志。
4、异常在子父类覆盖中的体现:
1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或该异常的子集。
2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3.如果父类或接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理,绝对不能抛。

六、应用

  1. /* 
  2. 需求: 
  3. 1、获取长方形和圆形面积。 
  4. 2、自定义面积出现非法的数值时的异常处理。 
  5. */  
  6. //用异常描述封装对象 优点:将正常流程代码和问题处理代码分开处理,提高代码阅读性。  
  7. class NoValueException extends RuntimeException  
  8. {  
  9.     NoValueException(String message)  
  10.     {  
  11.         super(message);  
  12.     }     
  13. }  
  14.   
  15. interface Shape  
  16. {  
  17.     void getArea();  
  18. }  
  19. //长方形实现形状   
  20. class Rec implements Shape   
  21. {  
  22.     private int len,wid;  
  23.     Rec(int len,int wid)  
  24.     {  
  25.         if(len<=0 || wid <=0)  
  26.             throw new NoValueException("出现非法值");  
  27.           
  28.         this.len = len;  
  29.         this.wid = wid;  
  30.     }  
  31.     public void getArea()  
  32.     {  
  33.         System.out.println(len*wid);  
  34.     }  
  35. }  
  36. //圆的实现形状   
  37. class Circle implements Shape  
  38. {  
  39.     private int radius;  
  40.     //运用final单独定义常量。   
  41.     public static final double PI = 3.14;  
  42.       
  43.     Circle(int radius)  
  44.     {   
  45.         if(radius<=0)  
  46.             throw new NoValueException("非法");  
  47.         this.radius = radius;  
  48.     }  
  49.     public void getArea()  
  50.     {  
  51.         System.out.println(radius*radius*PI);  
  52.     }  
  53. }  
  54.   
  55. class ExceptionTest  
  56. {  
  57.     public static void main(String[] args)  
  58.     {  
  59.         Rec r = new Rec(3,4);  
  60.         r.getArea();  
  61.           
  62.         Circle c = new Circle(-5);  
  63.         c.getArea();  
  64.         System.out.println("over");  
  65.     }  
  66. }  
输出结果:


一、定义

包(package):是一种通过提供多层命名空间,对类文件进行分类管理的工具。
作用:进行类组区分,方便对类进行管理;同时包可以将java的类文件和源文件相分离,便于数据分享;

二、特点

1、写在程序文件第一行;因为先有房子,才能放家具。
2、类名的全称是 包名.类名;如:创建a包中Demo对象  a.Demo d = new a.Demo();
3、是一种封装形式。包、类、方法都是封装对象,私有并不代表封装,它只是封装的一种形式。

三、格式

1、自动生成包的编译格式:javac -d <目录> 文件名 

-d <目录> : 指定存放生成的类文件(class文件)的位置 

例:javac -d . PackageDemo.java 注意:".":代表当前目录,它前后的空格不可省略。

四、包之间的访问

1、要访问其他包中的类,需要定义类的全称:包名.类名。
2、包如果不在当前路径,需要使用classpath设定环境变量,为JVM指明路径。
3、被访问的包中的类权限必须是public的。

4、类中的成员权限:public或者protected。protected(保护):限制访问权限只能是其子类。类公有后,被访问的成员也要公有才可以被访问。

不同包中的子类可以直接访问父类中被protected权限修饰的成员。同一个包中,protected作用只为覆盖。

5、访问四种权限


注:
一个java文件里面,不能出现两个以上的公有类或者接口。因为被public修饰的类名必须与java文件名相同。 

五、包的导入(import)

1、可以简化类名。在调用其他包中的类时,需要写类的全称,也就是连同包名一起书写。当类存在多层包中时,

如:haha.hehe.pack.Demo,使用import导入后,使用其类时,就可以不加包名了。

导入格式如:import haha.hehe.pack.Demo;

2、一个程序文件中只有一个package,可以有多个import。import导入的是包中的类,不导入包中的包。
3、注意事项:
a、在导入包时,如果包中有很多类,可以使用通配符 *来替代包中的所有类。但是,建议不要使用通配符 * ,因为将不需要使用的类导入后,会占用内存空间。

b、定义包名不要重复,可以使用url来完成定义,url是唯一的。

如:package cn.itheima.Demo。

c、导入的不同包中有相同类时,必须写类的全名以区分,否则将会报错。

六、jar包

类越来越多,我们可以用包来装,当包越来越多时,我们可以将包进行压缩。而java中用jar这个工具来对包进行压缩。压缩后的后缀名为jar。
jar包的优点:
1、可以将多个包进行压缩到为一个文件。方便项目的携带。
2、方便于使用,只要在classpath设置jar路径,即可以执行jar包中的java程序。
3、数据库驱动、SSH框架等都是以jar包体现的。
  1. jar.exe工具常见命令:  
  2. a、创建jar包  
  3. jar  -cvf  mypack.jar packa packb  
  4. b、查看jar包  
  5. jar  -tvf  mypack.jar  [>定向文件]  
  6. c、解压缩  
  7. jar  -xvf  mypack.jar  
  8. d、自定义jar包的清单文件  
  9. jar –cvfm  mypack.jar mf.txt  packa packb  

PS:
D:\java8\jre\lib\rt.jar java的类库
tools.jar 编译工具类包
src.zip  java所有类的源文件

七、应用

  1. package packb;  
  2.   
  3. //包之间访问,被访问的包中的类和方法权限都必须是public。  
  4. public class DemoB  
  5. {  
  6.     public void method()  
  7.     {  
  8.         System.out.println("demob method run");  
  9.     }  
  10. }  
  1. package packa;  
  2.   
  3. //被继承的类要写全称   
  4. public class DemoA extends packb.DemoB  
  5. {  
  6.     public void show()  
  7.     {  
  8.         System.out.println("demoa show run");  
  9.         method();  
  10.     }  
  11.       
  12. }  
  1. //建立名为pack的包。一个程序文件中只有一个package,但可以有多个import  
  2. package pack;  
  3. import packa.*;  
  4. import packb.*;  
  5.   
  6. class PackageDemo  
  7. {  
  8.     public static void main(String[] args)  
  9.     {  
  10.         /* 
  11.         //类名全称为:包名.类名 
  12.         //导入包前写法 
  13.         packa.DemoA a = new packa.DemoA(); 
  14.         a.show(); 
  15.         */  
  16.         //导入后写法   
  17.         DemoA a = new DemoA();  
  18.         a.show();  
  19.     }  
  20. }  
输出结果:

  1. PS:  
  2. 包常见问题:  
  3. 1、PackageDemo.java:8: 错误: 找不到符号  
  4.                 DemoA a = new DemoA();  
  5.                 ^  
  6.   符号:   类 DemoA  
  7.   位置: 类 PackageDemo  
  8.   
  9. 错误原因:类名写错  
  10. 因为类名的全名是: 包名.类名  
  11.   
  12. 2、PackageDemo.java:8: 错误: 程序包packa不存在  
  13.                 packa.DemoA a = new packa.DemoA();  
  14.   
  15. 错误原因:packa包不在当前目录下,需设置classpath  set classpath=目标文件地址  
  16.   
  17. 3、PackageDemo.java:8: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行访问  
  18.                 packa.DemoA a = new packa.DemoA();  
  19.   
  20. 错误原因:DemoA的访问权限不够(类的权限修饰符有:public default)  
  21. 有了包,范围变大,一个包中的类要被访问,必须要有足够大的权限,所以被访问的类要被public修饰。  
  22.   
  23. 4、PackageDemo.java:9: 错误: show()在DemoA中不是公共的; 无法从外部程序包中对其进行 访问  
  24.                 a.show();  
  25.                  ^  
  26. 错误原因:类公有后,被访问的成员也要公有才可以访问。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1829次
    • 积分:122
    • 等级:
    • 排名:千里之外
    • 原创:11篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档