黑马程序员——异常处理

来源:互联网 发布:linux lamp包 编辑:程序博客网 时间:2024/06/05 16:59
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

1、异常

异常:就是不正常,是指程序在运行时出现的不正常情况。其实就是程序中出现的问题。这个问题按照面向对象思想进行描述,并封装成了对象。因为问题的产生有产生的原因、有问题的名称、有问题的描述等多个属性信息存在。当出现多属性信息最方便的方式就是将这些信息进行封装。异常就是java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。

 

出现的问题有很多种,比如角标越界,空指针等都是。就对这些问题进行分类。而且这些问题都有共性内容比如:每一个问题都有名称,同时还有问题描述的信息,问题出现的位置,所以可以不断的向上抽取。形成了异常体系。 

 

异常的体系  Throwable

Error

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

不需要编写针对代码对其处理,程序无法处理。

Exception 

在运行时运行出现的一些情况,可以通过try,catch,finally处理

 

异常处理两种方式:

1、捕获异常:try catch 直接处理可能出现的异常!

2、声明异常:throws 声明告诉调用者可能的异常,暴露问题,调用者自己处理!

 

我的总结:

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

Java异常其实是对不正常情况的一种描述,并将其封装成对象;

Java在 设计异常体系时,将容易出现的异常情况都封装成了对象。

 

 

2、异常处理格式

 

异常处理的5个关键字

try ,catch,

finally 

throw, throws

 

我的总结:

捕获异常:先捕获小异常再捕获大异常。

程序是调出来的,不是写出来的;多测试是程序员的必修课。

异常处理后,程序不会因为出现异常而退出!

 

 

异常处理格式

try{

//可能出异常的代码

} catch(异常类  对象){

//处理该异常类型的语句

}

[finally] {

//一定会执行的代码

//catch块使用System.exit(1);除外

}

 

备注:当try语句块出现异常,程序会自动跳到catch语句块去找匹配的异常类型,并执行异常处理语句,finally语句块是异常的统一出口。

 

 

3、多异常处理

声明异常时尽可能声明具体异常类型,方便更好的处理;

方法声明几个异常就对应有几个catch;

若多个catch块中的异常出现继承关系,父类异常catch块放在最后;

catch语句块使用Exception类作为异常类型时:

所有子类实例都可以使用父类接收(向上转型),即所有的异常对象都可以使用Exception接收;

注:在java处理多异常时捕获小范围的异常必须放在大范围异常之前。

 

java7 - 同时捕获多个异常类型

Java7之前:

try {

int a = Integer.parseInt("1");

int b = Integer.parseInt("0");

int c = a / b;

System.out.println(c);

} catch (NumberFormatException e)

{

   e.printStackTrace();

} catch(ArithmeticException e) 

{

e.printStackTrace();

}

 

Java7将多个异常写到了同一个catch代码块

try {

Integer a = Integer.parseInt("1");

Integer b = Integer.parseInt("0");

 

Integer c = a / b;

 

System.out.println(c);

 

} catch (NumberFormatException 

| ArithmeticException  e ) {

 e.printStackTrace();

}

 

4异常的分类

 

异常分类:

编译时被检查异常 ---> Checked异常

在程序中必须使用try...catch处理;

编译时不被检测的异常; ---> Runtime异常

可以不使用try...catch处理,但一旦出现异常就将由JVM处理。

 

异常的分类之Runtime异常

 

 

RuntimeException(运行时异常)是指因设计或实现方式不当而导致的问题.

说白了,就是程序员造成的,程序员小心谨慎是完全可以避免的异常.比如,事先判断对象是否为null就可以避免NullPointerException异常,事先检查除数不为0就可以避免ArithmeticException异常;

 

特点:

这种异常Java编译器不会检查它,也就说程序中出现这类异常的时候,即使不处理也没有问题,但是一旦出现异常,程序将异常终止,若采用异常处理,则会被相应的程序执行处理.

 

异常的分类之Checked异常

 

除了RuntimeException以及子类,其他的Exception及其子类都是受检查异常,我们也可以称为非RuntimeException异常.

特点:

Java编译器会检查它,也就说程序中一旦出现这类异常,要么是没有try-catch语句捕获,throws语句没有声明抛出它,编译就不会通过,也就说这种异常,程序要求必须处理.

 

5、声明异常(throws

 

在可能出现异常的方法上声明抛出可能出现异常的类型:

声明的时候尽可能声明具体的异常,方便更好的处理.

当前方法不知道如何处理这种异常,可将该异常交给上一级调用者来处理(RuntimeException类型的异常)

方法一旦使用throws声明抛出方法内可能出现的异常类型, 该方法就可以不再过问该异常了;

一个方法调用另一个使用throws声明抛出的方法,自己要么try...catch , 要么也throws;

 

格式:

public 返回值类型  方法名(参数列表...) 

throws 异常类A,异常类B... {

}

 

6throw

自行抛出一个异常对象,抛出异常类的对象;

throw抛出的是Runtime异常:

程序可以显示使用try...catch来捕获并处理,也可以不管,直接交给方法调用者处理;

throw抛出Checked异常:

要么放在try里自己处理,要么放在一个throws声明的方法里面,交给调用者处理。

 

 

Eg

public static void main(String[] args) {

try {

      fn1(1);

} catch (Exception e) { e.printStackTrace(); }

fn2(2);

}

public static void fn1(int a) throws Exception{

if(a >0) { throw new Exception("fn1 -- a值不合法"); }

}

public static void fn2(int a) {

if(a >0) { throw new RuntimeException("a值不合法"); }

}

 

throws & throw

 

throws用于在方法上声明该方法不需要处理的异常类型。

throw用于抛出具体异常类的对象。

throwsthrow的区别:

thorws用在方法上,后面跟异常类名,可以是多个异常类。

throw用在方法内,后面跟异常对象,只能是一个。

 

7finally

 

异常的统一出口:

不管try块程序是否异常,也不管哪个catch执行,finally块总会执行。

try语句块或会执行的catch语句块使用了JVM系统退出语句例外;//System.exit(1);

try块必须和 catch块或和finally同在,不能单独存在,二者必须出现一个。

不要在finally中使用return throw语句,否则将会导致trycatch中的returnthrow失效。

 

我的总结:finally代码块只在一种情况下不执行:System.exit(0)

 

Eg

package reviewDemo;

 

public class Demo19 {

public static void main(String[] args) {

try{

System.out.println(17/0);

}catch(Exception e){

//e.printStackTrace();

System.out.println("程序错误,请修正!");

}finally{

System.out.println("这是finally代码块!");

}

}

}

 

输出:

程序错误,请修正!

这是finally代码块!

 

8throwcatch同时使用

 

当异常出现在当前方法中,程序只对异常进行部分处理,还有一些处理需要在方法的调用者中才能处理完成,此时还应该再次抛出异常,这样就可以让方法的调用者也能捕获到异常;

 

Eg

public static void buy(String price) throws Exception {

try {

if(price != null)

Double.parseDouble(price);

} catch (Exception e) {

e.printStackTrace();

throw new Exception("价格不能只能是数字组成");

}

}

public static void main(String[] args)  {

try {

buy(null);

} catch (Exception e) {

System.out.println(e.getMessage());

}

}

 

 

 

 

 

 

 

9、常用类

String

String表示字符串,所谓字符串,就是一连串的字符;

String是不可变类,一旦String对象被创建,包含在对象中的字符序列(内容)是不可变的,直到对象被销毁;

 

常量池:JVM中一块独立的区域存放字符串常量和基本类型常量(public static final)。

String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的.

String对象比较:

单独使用""引号创建的字符串都是常量,编译期就已经确定存储到常量池中;

使用new String("")创建的对象会存储到堆内存中,是运行期新创建的;

使用只包含常量的字符串连接符如"aa" + "bb"创建的也是常量,编译期就能确定,已经确定存储到常量池中;

使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在堆中;

 

Eg

package string;

 

public class StringDemo {

public static void main(String[] args) {

/*

 *  "" 其实表示的是  String的匿名对象

 */

String s = "";

/**

 * String()    初始化一个新创建的 String 对象,使其表示一个空字符序列。

 *  "",不是表示 null

 *  String(String original) 

 *  String s = new String("asd");// s 的值就是 asd

 */

s = new String();//""

String s1  = new String("11");

String s2  = new String("11");

System.out.println(s1 == s2);//false

String s3 = "22";

String s4 = "22";

System.out.println(s3 == s4);//true

System.out.println(s3 == s2);//false

String  s5 = "2" + "2";//这句话其实在编译器编译后的class文件中 已经变成  "22"

//s5创建了几个对象?//回答:最多一个,如果常量池里面没有就是创建一个,如果常量池里本来就有就是创建零个!下面的str一样的道理。

String str = "A" +"B"+ "C" +"D" +"E";//String str = "ABCDE";

System.out.println(s3 == s5);//true

/**

 * String特点:   不可变的,  一个String对象的内容不能变,一旦内容变量该对象就变成一个新的String对象了

 *  String  str = "AAA";

 *  str = str+"12";

 */

String str1 = "ABCDE";

System.out.println(str == str1);//true

String str2 = "ABC" + "DE";

System.out.println(str == str2);//true

String  ss = "AB";

String str3 = ss + "CDE";//这里的str3在运行期才能确定内容值

System.out.println(str3 == str2);//false

String str4 = getStr() +"CDE";//在运行期才能确定 str4的值

System.out.println(str == str4);//false

System.out.println(str3 == str4);//false

/*

 *  String s = "cd"; //一个String对象

s = s + "itcast"; //itcast也是String对象最后的s的值cditcast,也是一个String对象

System.out.print(s);

 * */

}

public static String getStr(){

return "AB";

}

}

 

Eg:

package reviewDemo;

 

public class Demo20 {

public static void main(String[] args) {

//s1,s2只新建了一个对象

String s1 = "你好";

String s2 = "你好";

//s3,s4新建了两个对象

String s3 = "你好";

String s4 = "你好";

}

}

 

0 0