异常类有个最大的类叫Object类,而对于异常来说,Throwable才是基类。Throwable有两个大的子类,一个是Error类,一个是Exception。一般我们能处理的异常叫Errow,其一般是我们处理不了的。比如说虚拟机错误、栈溢出错误。一般是虚拟机打印出来,我们没有必要去打印出来。这些都属于程序员解决不了的错误。就在这个子类里,以及其分支下面的子类,但是都不需要处理。而我们能处理的类都属于Exception类,而Exception类又有两个大的分支——RuntimeExcpetion类和
RuntimeExcpetion叫运行时异常,又叫非受控异常,而其他的叫非运行时异常。比如下面代码中抛出的ArrayIndexOutOfBoundsException、NumberFormatException和ArithmeticException三个异常,在c++里其实都可以不处理,而代码依然可以编译,甚至执行。
public class Caculate1 {
/**
* 对两数求商
*/
public static void main(String[] args) {
//这里没有长度参数,因为数组自己有长度。
try {
//当出异常时,虚拟机判断异常,
//然后生成异常对象的封装过后的代码,并打印出来。
String num1 = args[0];
String num2 = args[1];
int n1 = Integer.parseInt(num1);
int n2 = Integer.parseInt(num2);
System.out.print(n1 / n2);
} catch (ArrayIndexOutOfBoundsException e) {
//catch为捕获异常
//System.out.print(e);//此异常代码打印的有点少
e.printStackTrace();//此为打印栈帧中信息
//之所以要写这么多catch,
//是因为每个catch只能捕获一个异常。
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (ArithmeticException e) {
//除零异常属于数学异常
e.printStackTrace();
}
}
}
注意:以下类的参数设定都需要在Run菜单下的Configuration目录里找Application属性框,对里面的参数进行设定。
常见异常:
空指针异常:
字符串为空,所有方法无法被调用。即当报空指针该异常的时候,我们要反应过来,看看到底是哪个引用是空的,没有被new出来。引用只是一个指针,一个8个字节的变量,只能保存地址,内存不够用来保存方法。
而没有对象的结决方法就是,我们new一个对象,或者直接写一个对象即可。但是,当我们只这样编写,也是不对的。
String[] ss=new String[100];
这里指向的内存保存的并不是100个字符串,而是100个地址(800个字节(64位))。ss引用指向了一块内存,但是那块内存里边有100个引用。虽然确实new了,但是new的并不是字符串,而是100个地址。我们将其如下方法遍历出来,也是会报错的。
for (int i=0;i<ss.length;i++){
System.out.print(ss[i].length());
}
而只有如下这样才能打印出值来:
for (int i=0;i<ss.length;i++){
ss[i]=new String("sasdfsdaf");
System.out.print(ss[i].length());
}
类转换异常
public class 类转换异常 {
public static void main(String[] args) {
Animal a=new Bird();
((Bird)a).out();
//子类引用可以转换算成父类地址,
//但是父类就不行。而这里将a强制转换成子类,
//才得以让调用Bird的子类。
a=new Fish();
//同理,钓鱼的方法也一样。
((Fish)a).in();
//但是,这里要注意的是,
//下面的转换是错误的,Fish类不能被转化成Bird类。
//因为这时,a指向的是Bird类,
// 但是现在调用的确是Fish的类,必定出错。
((Bird)a).out();
}
}
抛出关键字
虚拟机在判断完异常之后,要将消息告诉判断的人。那么,虚拟机接着就会将异常扔出来。/虚拟机先new一个异常类,而每一个异常类都有一个构造。
这个异常类的作用在于,我们可以自己定义异常消息,并且通过该异常类的构造传进该类。这样就把系统默认的异常给覆盖了。但是,光把异常new出来还不行,还要抛出。而且,异常要先被new出来,被保存之后,才能被抛出。这样RunTimeException ,才能被用来做为保存我们自己的异常信息的类了。这里Exception也可以捕获该异常,但是这是非运行时异常,必须要我们解决异常之后,才能运行。然而,这个办法却是大多数新手编写程序时的首选。
public class 抛出关键字 {
public static void main(String[] args) {
try {
String num1 = args[0];
String num2 = args[1];
int n1 = Integer.parseInt(num1);
int n2 = Integer.parseInt(num2);
if (n2 == 5) {
throw new RuntimeException("我这里除5也不行");
}
System.out.print(n1 / n2);
} catch (Exception e) {
e.printStackTrace();
}
}
}