Java程序设计(6)

七、异常

1. Throwable的子类包含哪两类?简述Java Error类与Exception类的区别。

Throwable的子类包含Error类和Exception类。

 

Error: 致命异常。标识系统发生了不可控的错误。程序无法处理,只能人工介入。例如, 虚拟机产生的错误StackOverflowError、OutOfMemoryError。

Exception: 非致命异常。程序可处理。分为受编译器检测的checked异常(受检异常)和不受编译器检测的unchecked异常(非受检异常)。


2. Exception又分为checked异常和unchecked异常,请分别举例说明。

派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常。


区别1:
checked exception 必须被显式的抛出或者捕获,比如FileNotFoundException,是一个必须处理的异常。
unchecked exception 不用被显式的抛出或者捕获,比如NullPointerException。

区别2:
checked exception继承Exception类
unchecked exception 继承RuntimeException类


3.请查阅资料,简述StackOverflowError和OutOfMemoryError两类错误的发生情形和原因。

1、线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError 异常。
递归可能造成StackOverflowError;不断创建线程可能造成StackOverflowError

2、栈的深度(大小类似于弹夹深度)可以自动扩展,扩展时无法申请到足够的内存时会抛出OutOfMemoryError异常。

3、虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError 和OutOfMemoryError
异常。

4、如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常。

5、当方法区无法满足内存分配需求时,将抛出OutOfMemoryError 异常。

6、当常量池(方法区的一部分)无法再申请到内存时会抛出OutOfMemoryError 异常。

7、各个内存区域的总和大于物理内存限制(包括物理上的和操作系统级的限制),从而导致动态扩展时出现OutOfMemoryError异常。


4.简述异常处理的两种方式,并举例说明区别。

 

 

 

声明抛出处理:当一个方法出现错误引发异常时,方法创建异常对象并交付运行时系统,异常对象中包含了异常类型和异常出现时的程序状态等异常信息。运行时系统负责寻找处置异常的代码并执行。

程序捕获处理:在方法抛出异常之后,运行时系统将转为寻找合适的异常处理器(exception handler)。潜在的异常处理器是异常发生时依次存留在调用栈中的方法的集合。当异常处理器所能处理的异常类型与方法抛出的异常类型相符时,即为合适 的异常处理器。运行时系统从发生异常的方法开始,依次回查调用栈中的方法,直至找到含有合适异常处理器的方法并执行。当运行时系统遍历调用栈而未找到合适 的异常处理器,则运行时系统终止。同时,意味着Java程序的终止。

 

public class Test {
    public static void main(String[] args) { // doSome()可能抛出编译时异常,需要预先处理,2种处理方式
     // 第一种:方法声明位置上继续上抛,添加throws ClassNotFoundException
        
        // 第二种:使用try..catch进行捕捉
        try {
            doSome();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // ClassNotFoundException属于编译时异常,直接父类是Exception,没有通过RuntimeException父类
    private static void doSome() throws ClassNotFoundException {  //假设这个方法执行过程中会出现ClassNotFoundException异常
        System.out.println("doSome!!!");
    }
}


5.选取RuntimeException类的五个子类,编写抛出并捕获上述子类异常的程序。(例如算术异常, 空指针异常,类转换异常,数组越界异常等)

1.

EmptyStackException类:
抛出:

package test;
import java.util.*;
public class test1 {
    public static void main(String[] args) throws EmptyStackException{
        Stack st=new Stack();
        Object ob=st.pop();
    }
}
/*
Exception in thread "main" java.util.EmptyStackException
	at java.util.Stack.peek(Stack.java:102)
	at java.util.Stack.pop(Stack.java:84)
	at test.test1.main(test1.java:8)
*/

捕获:

package test;
import java.util.*;

public class test1 {
    public static void main(String[] args) {
        try {
            Stack st=new Stack();
            Object ob=st.pop();
        }
        catch(EmptyStackException e) {
            System.out.println("空栈异常");
        }
    }
}
//空栈异常

2.

ArithmeticException类:

抛出:

package test;

public class test1 {
	public static void main(String[] args) {
		int a,b,c;
		a=1;
		b=0;
		c=a/b;
		System.out.println(c);
	}
}
/*
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at test.test1.main(test1.java:8)
*/

捕获:

package test;

public class test1 {
	public static void main(String[] args) {
		try{
			int a,b,c;
			a=1;
			b=0;
			c=a/b;
			System.out.println(c);
		}
		catch(ArithmeticException e) {
			System.out.println("除数为0");
		}
			
	}
}
//除数为0

3.

NullPointerException类:
抛出:

package test;

public class test1 {
    private static int[] x;
    public static void main(String[] args) {
        System.out.println(x[0]);
    }
}
/*
Exception in thread "main" java.lang.NullPointerException
	at test.test1.main(test1.java:6)
*/

捕获:

package test;

public class test1 {
    private static int[] x;
        public static void main(String[] args) {
            try {
                System.out.println(x[0]);
            }
            catch(NullPointerException e) {
                System.out.println("空指针异常");
            }
        }
}
//空指针异常

4.

ArrayIndexOutOfBoundsException类:
抛出:

package test;

public class test1 {
    public static void main(String[] args) {
        String foo=args[1];
        System.out.println("foo="+foo);
    }
}
/*
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
	at test.test1.main(test1.java:5)
*/

捕获:

package test;

public class test1 {
    public static void main(String[] args) {
        try{
            String foo=args[1];
            System.out.println("foo="+foo);
        }
        catch(ArrayIndexOutOfBoundsException e) {
            System.out.println("数组下标越界");
        }
    }
}
//数组下标越界

5.

NegativeArraySizeException类:
抛出:

package test;

public class test1 {
    public static void main(String[] args) {
        int[] a;
        a=new int[-1];
    }
}
/*
Exception in thread "main" java.lang.NegativeArraySizeException
	at test.test1.main(test1.java:6)
*/

捕获:

package test;

public class test1 {
    public static void main(String[] args) {
        try{
            int[] a;
            a=new int[-1];
        }
        catch(NegativeArraySizeException e) {
            System.out.println("负数组长度异常");
        }
    }
}
//负数组长度异常


6.根据某业务场景自定义一个异常类,并在某场景下抛出该异常对象。

package test;

public class test1 extends Exception{
    public test1(String msg) {
        super(msg);
    }

    static void throwOne() throws test1{
        boolean exception=true;
        if(exception) {
            throw new test1("异常");
        }
    }

    public static void main(String[] args) {
        try {
            throwOne();
        }
        catch(test1 e) {
            e.printStackTrace();
        }
    }
}
/*
test.test1: 异常
	at test.test1.throwOne(test1.java:11)
	at test.test1.main(test1.java:17)
*/


7.异常中的throws声明与throw语句的区别是什么?请举例说明。

用户程序自定义的异常和应用程序特定的异常,必须借助于throws和throw语句来定义抛出异常。

1、throw是语句抛出一个异常。

语法:throw (异常对象);

throw e;

2、throws是方法可能抛出异常的声明,用在声明方法时,表示该方法可能要抛出异常。

语法:[(修饰符)](返回值类型)(方法名)([参数列表])[throws(异常类)]{......}

public void doA(int a) throws Exception1, Exception2{……}

举例:

throws E1,E2,E3只是告诉程序这个方法可能会抛出这些异常,方法的调用者可能要处理这些异常,而这些异常E1,E2,E3可能是该函数体产生的。throw则是明确了这个地方要抛出这个异常。

如:

public void doA(int a) throws IOException {
	try {
		……
	} catch (Exception1 e) {
		throw e;
	} catch (Exception2 e) {
		System.out.println("出错了!");
	}
	if (a != b)
		throw new Exception3("自定义异常");
}

(1)throw语句用在方法体内,表示抛出异常,由方法体内的语句处理;throws语句用在方法声明后面,表示再抛出异常,由该方法的调用者来处理。

(2)throws主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常;throw是具体向外抛异常的动作,所以它是抛出一个异常实例。

(3)throws出现在方法函数头;而throw出现在函数体。

(4)throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。

(5)两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。


8. finally子句的作用是什么?

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值