异常/错误:程序运行过程中,可能会发生一些不被期望的效果,肯定会阻止我们的程序按照指令去执行;
这种不被预期出现的效果,肯定需要抛出来告诉我们;
在java中有一个定义好的规则 Throwable(可以抛出的)
Error 错误;通常是一些物理性的;JVM虚拟机本身出现的问题;程序指令是处理不了的;
Exception异常 通常是一种人为规定的不正常的现象,通常是给定的程序指令产生了一些不符合规范的事;
Throwable类实现了一个序列化接口
Errro(错误) Exception(异常)
StackOverflowError(方法来回调用) RuntimeException(运行时) IOException
OutOfMemoryError(堆内存)
异常的分支体系
运行时异常(非检查异常)
Error和RuntimeException都算运行时异常
javac编译的时候,不会提示和发现的
在程序编写的时不要求必须做处理,可以添加处理手段(try throws)
常见的运行时异常:
1.InputMisMatchException 输入不匹配
int value=input.nextInt();//abc
2.NumberFormatException 数字格式化
int value=Integer.parseInt("123.45");
3.NegativeArraySizeException 数组长度负数;
int[] array=new int[-2];
4.ArrayIndexOutOfBoundsException 数组索引越界;
int[] a={1,2,3};
a[5];
5.NullPointerException 空指针异常
int[][] array=new int[3][];
6.ArithmeticException 数字异常
10/0 整数不允许除以0
7.ClassCastException 造型异常
Person p=new Teacher();
Student s=(Student)p;
8.StringIndexOutOfBoundsException 字符串越界
String a="adb";
a.charAt(5);
9.IndexOutOfBoundsException 集合越界
ArrayList a=new ArrayList();
a.add();
a.get(5);
10.IllegalArgumentException 非法参数异常
ArrayList a=new ArrayList(-1);
编译时异常(检查异常)
除了Error和RuntimeException以外其他的异常
javac编译的时候 强制要求我们必须为这样的异常做处理(try或throws)
因为这样的异常在程序运行过程中极有可能产生问题的
异常产生后后续的所有执行就停止啦;
1.InterruptException
try{
Thread.sleep(5000);
}catch(Exception e){
}
----------------------------------------------------------------------------------------------------
两种手段
方式一、try{} catch(){}[finally{}]
1.try不能单独处理
2.后面必须添加catch或finally
3.catch有一组() 目的是为了捕获某一种异常
4.catch可以有很多个存在
捕获的异常之间没有任何的继承关系
捕获的异常需要从小到大进行捕获
5.finally不是必须存在的
若存在finally结构,则必须执行
问题:final finally finalize区别;
final 特征修饰符 修饰变量 属性 方法 类
修饰变量 基本类型 值不能改变 引用类型 地址不能改变(如果变量没有初始值,给一次机会)
修饰属性 特点与修饰变量类似(要求必须给属性赋初始值 否则编译报错)
修饰类 不能被其他的子类继承
finally 处理异常手段的一部分
try{} catch(){}后面的一个部分
这个部分可有可无 如果有只能含有一份 且必须执行
finalize 是Object类中的一个protected方法
对象没有任何引用执行的时候 --会被GC回收
当对象回收的时候 默认调用finalize方法;
若想要看到对象回收的效果 可有重写public void finalize(){}
6.处理异常放在方法内部,可能有问题;
如果在方法内部含有返回值
不管返回值return关键字在哪里 finally一定会执行完毕;
返回值的具体结果 看情况
public class TestMain{ //public static void testException(){ public String testException(){ try{ System.out.println("try开始"); //String a=null; String a="abc"; a.length(); return "结果"; }catch(Exception e){ e.printStackTrace(); System.out.println("捕获到异常"); }finally{ System.out.println("finally块"); } return "末尾结果"; } public static void main(String[] args){ //TestMain.testException(); System.out.println(new TestMain().testException()); /* try{ System.out.println("try start"); String str="abc"; str.length(); str.charAt(5); }catch(NullPointerException e){ System.out.println("捕获到空指针"); }catch(StringIndexOutOfBoundsException e){ System.out.println("字符串越界"); }finally{ System.out.println("我是finally"); } System.out.println("klkj"); */ } }
方式二、throws抛出
1.异常只能在方法内产生的 属性是不能处理异常的;
2.方法 构造方法
3.方法可以抛出不止一个异常 通过,隔开
4.抛出的异常与多个catch类似 要么没关系 要么先抛出小异常;(谁调此方法,谁处理异常;主函数也可以抛出异常)
public class TestMain{ public TestMain() throws NullPointerException{ String a=null; a.length(); } public void testException() throws NullPointerException,StringIndexOutOfBoundsException{ String a=null; a.length(); a="abc"; a.charAt(10); } public static void main(String[] args){ try{ new TestMain().testException(); }catch(Exception e){ System.out.println("捕获异常"); } } }
我们也可以自己创建异常--自定义异常
1.自己描述一个异常的类
2.让我们自己的类继承
如果继承是RuntimeException --->运行时异常(不需要必须添加处理手段)
如果继承是Exception--->编译时异常(必须添加处理手段)
3.创建一个当前自定义异常类的对象
通过throw关键字 主动产生异常
4.当我们设计描述的方法(事情)之前没有相关的异常能描述我的问题
这个时候才会利用自定义异常来描述
package yic; public class MyException extends RuntimeException{ public MyException(){ } public MyException(String msg){ super(msg); } }
package yic; public class TestMain{ public void testMyException() throws MyException { System.out.println("测试"); if(3>2){ throw new MyException("说明异常具体原因"); } } public static void main(String[] args){ //System.out.println(10/0); TestMain te=new TestMain(); try{ te.testMyException(); }catch(Exception e){ e.printStackTrace(); } } }