异常体系:Exception&Error,Throwable 是 Exception和 Error的共同父类
一、Exception(异常)可以分为两类:
1、编译异常 2、运行异常其中,运行异常最为常见。
检查性异常------程序正确,但因为外在的环境条件不满足引发。例如:用户错误及I/O问题----程序试图打开一个并不存在的远程Socket端口。这不是程序本身的逻辑错误,而很可能是远程机器名字错误(用户拼写错误)。对商用软件系统,程序开发者必须考虑并处理这个问题。JAVA编译器强制要求处理这类异常,如果不捕获这类异常,程序将不能被编译。
1.编译时异常 编译时必须处理的异常
* FileNotFoundException
* 2.运行时异常 运行时出现的异常
* NullPointerException 一个为null的东西 调用方法或属性
* ArrayIndexOutOfBoundsException 索引超出指定的范围
* ClassCastException 发生在强制转型
* ArithmeticException 除0时出现
* IllegalArgumentException 参数非法
*
* 处理异常:
* 1.try catch finally
* 2.throws
* 自定义异常:throw 自定义的异常类的对象
*
*
1.try{//这里的异常是除数不能为0
int a = 10/0;
System.out.println("try--------");
//用来验证try和catch是否只能执行完一个,因为就像条件语句一样,进入是都可以的,但执行完就只有两者之一了
}catch(ArithmeticException e){//注意,异常类型是一定要写的
e.printStackTrace();
System.out.println("除数不能为0");
System.out.println("catch--------------");
}finally{//最后 始终都会执行 关闭资源(这是完整的步骤,一般会把finally省去)
System.out.println("finally-------");//验证finally永远都会执行
}
2.这种方法是直接把异常抛给虚拟机了,
用法是在出现异常的方法后面写throws +异常类型,
这是一种偷懒的方法,但是出来混总是要还的,每次有方法调用这个方法时候,那个方法也要用这种方式再次把异常抛给虚拟机
public class Test {
public static void main(String[] args) throws FileNotFoundException {
<span style="white-space:pre"> </span>/**
* x:\\1.txt可能不存在于电脑上
*/<span style="white-space:pre"> </span><pre name="code" class="java"><span style="white-space:pre"> </span>Test test = new Test();
<span style="white-space:pre"> </span>test.read();
}
public void read() throws FileNotFoundException{FileInputStream fis = new FileInputStream("x:\\1.txt");}}
3.暂时这个方法不会
二、 Error:(错误) 程序设计问题 * OutOfMemoryError 堆内存溢出 * StackOverflowError 栈内存溢出
堆溢出:堆存放的是对象,所以溢出的话,就是说对象太多的,但是现在这种情况很少会发生,一方面,内存已经足够大了,另一方面,Java有个垃圾回收机制,他会自动识别垃圾内存,并且回收。
但是还是会发生,例如:你闲的蛋疼的去申请一个超出内存的数组对象,比如内存是4G的,那就是有4*1024*1024*1024B,当然内存不全是堆,现在我们假设都是堆的话,你这样申请
int [] array = new int[1000000000];
那这样肯定超出内存了,这就是堆溢出
栈溢出:栈存放的是变量,他拥有堆中的对象的地址
那么栈何时会溢出呢?我们知道,递归的过程是一个不断压栈的过程,执行方法时,又调用方法本身时,这时本层的方法先压栈,再执行下一层的方法,这样一直执行,直到做到递归的出口时,才停止递归,不断地把每一层的结果依次返回到上一层。
倘若程序员没有没出递归的出口,那么这个递归就会无限制的调用方法本身,这样就会出现所谓的栈溢出,例如:计算n的累加之和
public int add(int n){
<span style="white-space:pre"> </span>return n+add(n-1);
}
这个就是错误的,因为没有给出递归的出口
修改如下:
public int add(int n){
<span style="white-space:pre"> </span>if(n>0){
<span style="white-space:pre"> </span>return n+add(n-1);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else return 0;
}
其实,更深入一些的话,可以这样问:请你计算栈的深度?
这时,我们就可以利用本来是错误的没有出口的递归,因为不同的内存大小的栈的长度不同。
上代码:
int count = 0;
public int count_stackLength(n){
<span style="white-space:pre"> </span>count++;
<span style="white-space:pre"> </span>system.out.println(count);
<span style="white-space:pre"> </span>return n+count_stackLength(n-1);
}
最后i,要多多了解异常,并且熟练的处理异常,避免出现ERROR,因为ERROR是程序员的错!!!