Java基础---异常,包
2015-09-08 15:40
447 查看
异常
1.定义
异常指的是在程序运行过程中发生的异常事件,通常是由硬件问题或者程序设计问题所导致的。在Java等面向对象的编程语言中异常属于对象。
Java异常类层次结构图:
2.异常由来:
编程中对于那些会出现的问题,Java采用异常机制来解决。 最常使用的就是try{}catch{} 本质:java对不正常情况进行描述后的对象体现。 程序可能出现的错误或问题: a、用户输入错误导致的异常:如用户不正常使用程序,输入一些非法参数 b、设备硬件等发生的错误:如硬盘损坏等 c、物理限制:如存储空间不足等 d、代码错误:在程序编写的方法可能不正确,数组越界,返回错误参数等。
3.异常体系
Throwable 类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw 语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。 有两个重要的子类:Exception(异常)和 Error(错误)
Error(错误)
是程序无法处理的错误,表示运行程序中较严重的问题。 这些错误表示故障发生于虚拟机自身、或者发生在虚拟机试图执行应用时,如Java虚拟机运行错误(Virtual MachineError)、类定义错误(NoClassDefFoundError)等。这些错误是不可查的,因为它们在应用程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况。对于设计合理的应用程序来说,即使确实发生了错误,本质上也不应该试图去处理它所引起的异常状况。在 Java中,错误通过Error的子类描述。
Exception(异常)
是程序本身可以处理的异常。 RuntimeException类是他的一个比较特殊的类。 RuntimeException 类: RuntimeException 类及其子类表示“JVM 常用操作”引发的错误。例如,若试图使用空值对象引用、除数为零或数组越界,则分别引发运行时异常(NullPointerException、ArithmeticException)和 ArrayIndexOutOfBoundException。
注意:异常和错误的区别:异常能被程序本身处理,错误是无法处理。
4.异常分类
1.Java的异常
Java的异常(包括Exception和Error)分为可查的异常(checked exceptions)和可不查的异常(unchecked exceptions)。
可查异常(编译器要求必须处置的异常):
程序在运行时,在一定程度上可以预知的异常,并可以采取某种方式进行处理。 除了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常。这种异常的特点是Java编译器会检查它,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
可不查异常(编译器不要求强制处置的异常):
包括运行时异常(RuntimeException与其子类)和错误(Error)。 这类异常编译时,编译器不会去检查。
2.Exception异常
Exception 这种异常分两大类运行时异常和非运行时异常(编译异常)。程序中应当尽可能去处理这些异常。
运行时异常:
RuntimeException及其子类,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等。这些异常编译器不检查,即使不使用try-catch捕获,或使用throws抛出,编译器也不会报错,但会在运行时触发。 这些异常一般出在逻辑上,在程序设计时应该从逻辑角度尽可能避免这类异常。
非运行时异常 (编译异常):
除RuntimeException及其子类外的异常,类型上属于Exception类及其子类。 编译器会检查此类一场,如果不处理,程序是无法编译通过的。
总结:根据编译器是否检查来进行划分。
总的来说,RuntimeException及其子类外的异常编译器不进行检查,其他Exception都需要处理。
异常处理
对于运行时异常、错误或可查异常,Java技术所要求的异常处理方式有所不同:a.运行时异常:java允许可以不抛出,不捕获;运行时由系统由系统抛出。 b.Error,不抛出,不捕获,因为Error是java所不允许发生的。 c.可查行异常,必须捕获或者抛出。
一个方法所能捕捉的异常,一定是Java代码在某处所抛出的异常。简单地说,异常总是先被抛出,后被捕捉的。
异常处理有两种方式:捕捉异常(try-catch),抛出异常(throws)
1.捕捉异常
java提供了特有的语句进行处理:try
{ 需要被检测的代码。 } catch(异常类 变量) { 处理异常的代码;(处理方式) } finally { 一定会执行的语句; }
注意:
1)finally中定义的通常是关闭资源代码。因为资源必须释放。 2)如果在一个功能中,定义了一些必须要执行的代码,可以用try{}finally{}的方式,将一定执行的代码放在finally代码块中。 3)finally只有一种情况不会执行。当执行到System.exit(0);fianlly不会执行。
public static void main(String[] args) { int a = 6; int b = 0; try { System.out.println("a/b的值是:"+ a / b); } catch (ArithmeticException e) { System.out.println("程序出现异常,变量b不能为0。"); } System.out.println("程序正常结束。"); } }
分析:此例中由try中监控区,检测到“除数为0”从而引发ArithmeticException异常,由异常处理器catch捕获,并处理。
但是,实际上,”除数为0“ArithmeticException异常是RuntimeException子类,会由系统自动抛出,不需要使用throw语句。
需要注意的是,一旦某个catch捕获到匹配的异常类型,将进入异常处理代码。一经处理结束,就意味着整个try-catch语句结束。其他的catch子句不再有匹配和捕获异常类型的机会。
对于有多个catch子句的异常程序而言,应该尽量将捕获底层异常类的catch子 句放在前面,同时尽量将捕获相对高层的异常类的catch子句放在后面。否则,捕获底层异常类的catch子句将可能会被屏蔽。
小结:
try 块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。 catch 块:用于处理try捕获到的异常。
finally块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。在以下4种特殊情况下,finally块不会被执行:
1)在finally语句块中发生了异常。
2)在前面的代码中用了System.exit()退出程序。
3)程序所在的线程死亡。
4)关闭CPU。
2.抛出异常
可以通过throws和throw抛出异常。1)throws
定义:
如果一个方法可能会出现异常,但没有能力处理这种异常,可以在方法声明处用throws子句来声明抛出异常。例如汽车在运行时可能会出现故障,汽车本身没办法处理这个故障,那就让开车的人来处理。
throws语句用在方法定义时声明该方法要抛出的异常类型,如果抛出的是Exception异常类型,则该方法被声明为抛出所有的异常。多个异常可使用逗号分割。throws语句的语法格式为:
methodname throws Exception1,Exception2,..,ExceptionN { }
方法名后的throws Exception1,Exception2,…,ExceptionN 为声明要抛出的异常列表。当方法抛出异常列表的异常时,方法将不对这些类型及其子类类型的异常作处理,而抛向调用该方法的方法,由他去处理。例如:
import java.io.*; public class Test1 { public static void method() throws IOException { File f = new File("r:\\"); } public static void main(String[] args) { //此处报错,Unhandled exception type IOException未处理异常 method(); } }
原因:IOException是Exception子类,是编译异常,必须捕获,method()方法使用throws向上层调用(main函数)抛出了,但是main函数未处理,所以造成了错误。
解决:使用try-catch捕获并处理。
Throws抛异常的原则:
1)不可查异常(unchecked exception)RuntimeException和Error异常可以不抛出,但是可查异常(checked exception)必须被抛出或者被捕获,否则编译会报错。 2)仅当抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。当方法的调用者无力处理该异常的时候,应该继续抛出,而不是囫囵吞枣。
public class Test1 { void method() throws IOException { File f = new File("r:\\"); } // 编译错误,必须捕获或者声明IOException void method1() { method(); } // 合法,声明抛出了IOException void method2() throws IOException { method(); } // 合法,声明抛出Exception,IOException是Exception的子类 void method3() throws Exception { method(); } // 合法,捕获了IOException void method4() { try { method(); } catch (IOException e) { } } // 不合法,又抛出了一个IOException,必须抛出或者再次捕获 void method5() { try { method(); } catch (IOException e) { throw new IOException(); } } // 合法,再次抛出的新的异常 void method6() throws Exception { try { method(); } catch (IOException e) { throw new Exception(); } } }
3)在子父类覆盖时: a,子类抛出的异常必须是父类的异常的子类或者子集。 b,如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
class T1 { void method() throws IOException { } } class T2 extends T1{ //错误,子类抛出的异常不是父类抛出异常的子类 void method()throws Exception { } }
2)throw抛出异常
在函数体内使用,即抛出一个一场对象。形如:
throw new Throwable();
该对象是人为抛出的,虽然和程序运行产生的不同,但是仍是需要抛出或者捕获的。
Throwable
Throwable中的方法:1.getMessage():获取异常信息,返回字符串。 2.toString():获取异常类名和异常信息,返回字符串。 3.printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void。 4.printStackTrace(PrintStreams):通常用该方法将异常内容保存在日志文件中,以便查阅。
自定义异常:
/*** * 自定义异常 */ class Demo{ //除法,抛出我的自定义异常 int div(int a, int b) throws MyException{ if(b==0){ throw new MyException("除数不能为负数!"); } return a/b; } } public class Test3 { public static void main(String[] args) { int a = 10; int b = 0; try { Demo d = new Demo(); int s = d.div(a, b); } catch (MyException e) { // TODO: handle exception e.printStackTrace(); System.out.println(e.getMessage()); } } } class MyException extends Exception { /*** * 自定义异常的构造方法,信息的传递通过有参构造方法, * 父类通过有参构造方法传递的参数来打印消息 */ public MyException(String MyMessage) { super(MyMessage); } }
小测试:
import java.util.*; /*** * 老师使用电脑讲课。 * * 描述电脑: 1、电脑运行 2、电脑重启 描述电脑问题: 1、电脑蓝屏了 2、电脑起火了 * * 描述老师: 1、老师使用电脑 2、老师讲课。 * * 描述老师可能出现的问题: * 1、老师不能继续讲课了。 * 2.电脑蓝屏,重新启动 * a.多次重启后,成功 * b.多次蓝屏重启后,电脑着火了 * 3.一次启动成功,老师开始讲课 */ //蓝屏异常 class BlueScreenException extends Exception { public BlueScreenException(String message) { super(message); } } //电脑着火 class FireBreakException extends Exception { public FireBreakException(String message) { super(message); } } //电脑类 class Computer { // 随机产生一个数,来模拟电脑启动 int i; //启动 void run() throws BlueScreenException, FireBreakException { i = (int) (Math.random()*3+1); if(1==i) { System.out.println("电脑正常启动"); } else if(2==i) { throw new BlueScreenException("电脑蓝屏了!");//蓝屏异常 } else { throw new FireBreakException("电脑着火了!");//着火异常 } } //重启 void reset() { System.out.println("电脑重新启动"); try { run(); } catch (BlueScreenException e) { System.out.println(e.getMessage()); reset(); } catch (FireBreakException e) { System.out.println("多次重启,着火了!"); } } } //无法上课的异常 class BreakTeachingException extends Exception{ public BreakTeachingException(String message){ super(message); } } //老师类 class Teacher{ private Computer c = new Computer(); void teach() throws BreakTeachingException{ try { c.run(); System.out.println("老师开始上课!"); } catch (BlueScreenException e) { System.out.println(e.getMessage()); c.reset(); } catch (FireBreakException e) { throw new BreakTeachingException("老师无法上课,原因"+e.getMessage()); } } } public class Test4 { public static void main(String[] args) { Teacher t = new Teacher(); try { t.teach(); } catch (BreakTeachingException e) { e.printStackTrace(); System.out.println("暂停上课,电脑着火了!"); } } }
一次启动成功,老师开始讲课:
一次启动,电脑着火:
多次蓝屏重启后成功
多次蓝屏重启后电脑着火
包
确保类的唯一性,使得同类名的类可以同时存在,使用包进行划分。权限问题:
规则
1、包必须写在程序的第一行。因为要先有包,才知道类文件的存放地方。 2、类的全称:包名.类名。 3、编译定义了包的程序文件时,在编译时要指定包的存储目录。 如:javac –d c:\mypack类名.java
jar包
创建jar包jar -cvf mypack.jar packa packb
查看jar包
jar -tvf mypack.jar [>定向文件]
解压缩
jar -xvf mypack.jar
自定义jar包的清单文件
jar –cvfm mypack.jar mf.txt packa packb
单个包打成jar包:
进入cmd:
编译:
javac -d . Demo.java和javac -d f:\JavaDemo Demo.java的不同在于指定的目录不同。
jar包生成:
运行:把生成的jar包放到D盘下,设置classpath路径,并运行。
多个不同包下的类建jar包:
同理:javac –d . Demo.java分别编译
建好后:
相关文章推荐
- Java工具类
- struts2 action动态方法调用
- 今天这个是mybatis与spring的整合
- java中的中文乱码处理
- Java String的经典问题(new String() ,String )
- struts2
- Description Resource Path Location Type Java compiler level does not match the version of the instal
- SpringMVC从Controller跳转到另一个Controller
- spring4声明式事务—02 xml配置方式
- spring_150805_datasource
- 关于spring mvc web工程上传下载中文文件出现乱码的问题
- java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)
- Java中的转义字符
- Java中的转义字符
- eclipse安装反编译插件
- eclipse安装反编译插件
- 【Java基础】--异常处理
- java script3
- spring mvc3中的addFlashAttribute方法
- 怎么样导入JAVA类?