异常

来源:互联网 发布:ugm和mac队关系 编辑:程序博客网 时间:2024/05/20 06:09

三.异常

1.异常语句

  2.3.1 try语句可能会抛弃一个或多个例外。  

  2.3.2 catch语句,包括一个例外类型和一个例外对象。例外类型必须为Throwable类的子类,它指明

了catch语句所处理的例外类型,例外对象则由运行时系统在try所指定的代码块中生成并被捕捉,大括号

中包含对象的处理,其中可以调用对象的方法。  

  catch语句可以有多个,分别处理不同类的例外。Java运行时系统从上到下分别对每个catch语句处理

的例外类型进行检测,直到找到类型相匹配的catch语句为止。  

  也可以用一个catch语句处理多个例外类型,这时它的例外类型参数应该是这多个例外类型的父类。

  2.3.3 finally语句

  finally所指定的代码都要被执行,通常在finally语句中可以进行资源的清除工作。如关闭打开的文

件等。  

  2.3.4 throws语句

  throws总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常。假如你想明确地抛出一

个RuntimeException,你必须用throws语句来声明它的类型。  

  2.3.5 throw语句

  throw总是出现在函数体中,用来抛出一个异常

  3 要害字及其中语句流程详解

  3.1try的嵌套

  每当碰到一个try语句,异常的框架就放到堆栈上面直到所有的try语句都完成。假如下一级的try

语句没有对某种异常进行处理,堆栈就会展开,直到碰到有处理这种异常的try语句。下面是一个try语句

嵌套的例子。  

  classMultiNest {  

  staticvoid procedure() {  

  try {  

  int a = 0;  

  int b =42/a;  

  } catch(java.lang.ArithmeticExceptione) {  

  System.out.println("inprocedure, catch ArithmeticException: " + e);  

  }  

  }  

  publicstatic void main(String args[]) {

   try {

  procedure();

   }catch(java.lang. Exception e) {

  System.out.println("in main, catch Exception: " + e);

   }

   }

  }

  这个例子执行的结果为:

  inprocedure, catch ArithmeticException: java.lang.ArithmeticException: / by zero

  成员函数procedure里有自己的try/catch控制,所以main不用去处理 ArrayIndexOutOfBoundsException;当然如果在procedure中catch到异常时使用throw e;语句将异常抛出,那么main当然还是能够捕捉并处理这个procedure抛出来的异常。例如在procedure函数的catch中的System.out语句后面增加throwe;语句之后,执行结果就变为:

in procedure, catch ArithmeticException:java.lang.ArithmeticException: / by zero

in main, catch Exception: java.lang.ArithmeticException: / by zero

    我认为try catch和正常的if else一样都是程序流程块,同样他们内部定义的变量对外部都是不可见的。如果try中的程序执行过程中有异常e抛出,如果e是catch中的定义的异常或是其子类,那么程序就会跳转到catch那边执行catch中的程序如果catch中的程序又有异常抛出那么就看这个异常有没有新的try catch块来捕获它,如果没有的话,那它就抛出了,程序中止执行。关于finally的理解就是任何调用try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,编译器把finally中的return实现为一个warning。

3.5 如何抛出异常

如果你知道你写的某个函数有可能抛出异常,而你又不想在这个函数中对异常进行处理,只是想把它抛出去让调用这个函数的上级调用函数进行处理,那么有两种方式可供选择:

第一种方式:直接在函数头中throws SomeException,函数体中不需要try/catch。

第二种方式:使用try/catch,在catch中进行一定的处理之后(如果有必要的话)抛出某种异常。

第三种方法:使用try/catch/finally

2.error和exception有什么区别?

error和exception区别:error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况;exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

System.err是将错误打印到控制台的标准错误流,通常比System.out要好,因为System.out也许会被重定向,而如果把结果送到System.err,就不会随System.out一起被重定向。

4.常见到的runtime exception。

ArithmeticException(除数为0的异常), BufferOverflowException(缓冲区上溢异常), BufferUnderflowException(缓冲区下溢异常), IndexOutOfBoundsException(出界异常),NullPointerException(空指针异常), EmptyStackException(空栈异常), IllegalArgumentException(不合法的参数异常), NegativeArraySizeException, NoSuchElementException,SecurityException, SystemException, UndeclaredThrowableException

1. java.lang.NullPointerException
  异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,即把数组的初始化和数组元素的初始化混淆起来了。数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)
  2. java.lang.ClassNotFoundException  异常的解释是"指定的类不存在"。
  3. java.lang.ArithmeticException  这个异常的解释是"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常
  4. java.lang.ArrayIndexOutOfBoundsException
  异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。
  5. java.lang.IllegalArgumentException
  这个异常的解释是"方法的参数错误",比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误
  6. java.lang.IllegalAccessException
  这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常。

5.Java中的异常处理机制的简单原理和应用。

  Java通过面向对象的方法来处理例外。在一个方法的运行过程中,假如发生了例外,则这个方法生成

代表该例外的一个对象,并把它交给运行时系统,运行时系统寻找相应的代码来处理这一例外。我们把生

成例外对象并把它提交给运行时系统的过程称为抛弃(throw)一个例外。运行时系统在方法的调用栈中查找从生成例外的方法开始进行回溯,直到找到包含相应例外处理的方法为止,这一个过程称为捕捉(catch)一个例外。 

当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发IndexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

6.运行时异常与一般异常有何异同?

Throwable是所有Java程序中错误处理的父类,有两种资类:Error和Exception。

   Error:表示由JVM所侦测到的无法预期的错误,由于这是属于JVM层次的严重错误,导致JVM无法继续执行,因此,这是不可捕捉到的,无法采取任何恢复的操作,顶多只能显示错误信息。

Exception:表示可恢复的例外,这是可捕捉到的。

Java提供了两类主要的异常:runtime exception和checkedexception。checked异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常。对于这种异常,JAVA编译器强制要求我们必需对出现的这些异常进行catch。所以,面对这种异常不管我们是否愿意,只能自己去写一大堆catch块去处理可能的异常。

    但是另外一种异常:runtime exception,也称运行时异常,我们可以不处理。当出现这样的异常时,总是由虚拟机接管。比如:我们从来没有人去处理过NullPointerException异常,它就是运行时异常,并且这种异常还是最常见的异常之一。

    出现运行时异常后,系统会把异常一直往上层抛,一直遇到处理代码。如果没有处理块,到最上层,如果是多线程就由Thread.run()抛出,如果是单线程就被main()抛出。抛出之后,如果是线程,这个线程也就退出了。如果是主程序抛出的异常,那么这整个程序也就退出了。运行时异常是Exception的子类,也有一般异常的特点,是可以被Catch块处理的。只不过往往我们不对他处理罢了。也就是说,你如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。

    如果不想终止,则必须扑捉所有的运行时异常,决不让这个处理线程退出。队列里面出现异常数据了,正常的处理应该是把异常数据舍弃,然后记录日志。不应该由于异常数据而影响下面对正常数据的处理。在这个场景这样处理可能是一个比较好的应用,但并不代表在所有的场景你都应该如此。如果在其它场景,遇到了一些错误,如果退出程序比较好,这时你就可以不太理会运行时异常,或者是通过对异常的处理显式的控制程序退出。

异常处理的目标之一就是为了把程序从异常中恢复出来

7.Throwable类

用面向对象的方法处理例外,就必须建立类的层次。类 Throwable位于这一类层次的最顶层,类Throwable有两个直接子类:Error和Exception。Error类对象(如动态连接错误等),Java虚拟机生成并抛弃(通常,Java程序不对这类例外进行处理);Exception类对象是Java程序处理或抛弃的对象。其中RuntimeException代表运行时由Java虚拟机生成的例外,如算术运算例外ArithmeticException(由除0错等导致)、数组越界例外ArrayIndexOutOfBoundsException等;其它则为非运行时例外,如输入输出例外IOException等。Java编译器要求Java程序必须捕捉或声明所有的非运行时例外,但对运行时例外可以不做处理。  

Throwable所提供的方法:

 String toString():代表该Throwable对象的字符串表示法。

 String getMessage():返回和该对象相关的错误信息。

 void printStackTrace():将例外生成所发生的途径显示出来。

 voidprintStackTrace(PrintStream out):输出到一个PrintStream的数据流中,借此可将信息写到一个文件。

 voidprintStackTrace(PrintWriter out):输出到一个PrintWriter的数据流中。

  当程序需要捕捉数个不同的例外时,需要特别注意这些例外的顺序。应该按照类之间的阶层关系放置,越是基本的类越需放在后面的catch()区段。

catch(Exception e) {

System.err.println("caught anexception");

}

这段代码能捕获所有的异常,所以在实际使用时最好将其置于处理程序列表的末尾,防止跟随在后面的任何特殊异常控制器失效。

一个例外类至少需要包含一个默认的构造函数(用来显示默认的信息)及一个以String对象为参数的构造函数(用来显示用户提供的自订信息)。

20.const ,static有什么用途?(请至少说明两种)

(1)可以定义 const 常量

(2)const 可以修饰函数的参数、返回值,甚至函数的定义体。被const 修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。

const 用途

1 const 常量:该数不允许被改变,若改变编译器报错,定义时就要初始化,不然以后就再也没有机会初始化了

2 const 函数形参:f(const int a);表示该形参是一个输入形参,在函数里不能改变其值

3 const 指针:让指针本身为const 或者指针所指为const 或者两者同时为const

4 类的成员函数 const :表示该函数只能对成员变量进行只读操作

5 const 类的成员函数:返回值为const,使得其返回值不能左值

static 用途

1 static局部变量表示该变量不是auto型的,就是说,该变量在程序开始的时候创建,在程序结束的时候销毁,使用的时候沿用是那个一次的那个值

2 static 全局变量 表示该变量只能在本文件中使用,不能被其他文件使用

3 static 函数表示该函数只能在本文件中使用 不能被其他文件中的函数调用

4 static 类成员变量表示这个类被全类拥有该类的所有对象只有一份拷贝

5 static 成员函数表示这个函数被全类拥有 而且只能访问静态成员变量