异常——error(资源耗尽,JVM内部系统错误,代码一般处理不了)和excption(数组越界,空指针访问,代码可以处理)
-
java.lang.Throwable;异常体系的根父类
-
-------java.lang.Error:错误。JVM虚拟机无法解决的严重问题,jvm系统内部错误,资源耗尽
|------StackOverflow、OutOfMemoryError
-------java.lang.Exception:异常。我们可以编写针对性的代码进行处理 -
|——编译时异常:(受检异常)**在执行javac.exe命令时,出现的异常
- ClassNotFoundException——没有找到对应类
- FileNotFoundException——文件没有找到
- IOException——文件读写异常 -
|——运行时的异常:(非受检异常)**在执行java.exe命令时,出现的异常tE
- ArrayIndexOutBoundsException——数组越界
- NullPointerException——指针空指向
- ClassCastException——类型转换异常
- NumberFormatException——数据格式输入异常
- InputMismatchException——输入不一致异常
- ArithmeticException——算术异常
public void test8()
{ ClassNotFoundExceptionClass clz=Class.forName("java.lang.Stirng");
}public void test9()
{File file =new File("hello.txt");FileInputStream fis =new FileInputStream(file); //FileNotFoundException——文件没有找到int data =fis.read();//IOException——文件读写异常while(data !=-1){System.out.print((char)data);data=fis.read(); //IOException——文件读写异常}fis.close();
}public void test1()
{' ArrayIndexOutBoundsException——数组越界'int arr[]=new int[10];System.out.println(arr[10]);
}public void test2()
{' NullPointerException——指针空指向'String str="hello";str=null;System.out.println(str);
}public void test3()
{Object obj =new String(); //String 赋值给Object对象String str =(String)obj; //obj本身就是String类型字符串,所以不报错Date date =(Date)obj;但是现在变成Date, 'ClassCastException——类型转换异常'
}public void test4()
{'NumberFormatException——数据格式输入异常'String str ="123";str ="abc";int i=Integer.parseInt(str); //把str转化为int类型int i=123System.out.println(i)
}public void test5()
{InputMismatchException——输入不一致异常Scanner scanner =new Scanner(System.in);int num=scanner.nextInt(); //要求int类型,但是你输入的字符串或者其他东西System.out.println(num);
}public void test6()
{不在定义域内 ArithmeticException——算术异常int num=10;System.out.println(num/0);
}
生活中的异常
不是可以避免的,Scanner.nextInt(“abc”)
- 异常:数组越界,指针悬置,对象没有指向
- 语法错误:少了分号,冒号,没有定义变量就使用,等等导致编译过不了
- 逻辑错误:算法设计有误,结果不尽人意
异常是程序经常会出现的,发现错误的最佳时机是在编译阶段,也就是你试图在运行程序之前。但是, 在编译期间并不能找到所有的错误,有—些 NullPointerException 和
ClassNotFoundException 异常在编译期找不到,这些异常是 RuntimeException 运行时异常,这些 异常往往在运行时才能被发现。
我们写 Java 程序经常会出现两种问题, —种是 java.lang.Exception , —种是 java.lang.Error,都用来 表示出现了异常情况,下面就针对这两种概念进行理解。
常见error1——栈溢出
常见error2——堆异常
Exception异常(重点)
常见的编译时异常和运行时异常
Exception异常处理方法——易于维护代码,一般我们都是解决编译时的异常
方式一: try-catch-finally(捕获异常)——直接把狼打死
抛抓模型:
1、抛——try
程序在执行过程中一旦出现异常,就会出现异常的代码处,生成对应异常类的对象,并且此对象抛出。
一旦抛出,此程序后面代码不可以执行
2、抓——catch
针对于过程1中抛出的异常对象,进行捕获处理。此捕获处理的过程中,就称之为抓。一旦将异常进行,后续代码就可以继续执行。
try {可能产生异常的代码 ——抛出异常对象
}
catch(异常类型1 e){//当产生了异常1执行的措施 ——错误匹配上了就执行catch里面的代码,否则不执行
}
catch(异常类型2 e){//当产生了异常2执行的措施
}
finally{无论是否发生异常都会执行的语句
}
public void test9()
{File file =new File("hello.txt");FileInputStream fis =new FileInputStream(file); //FileNotFoundException——文件没有找到int data =fis.read();//IOException——文件读写异常while(data !=-1){System.out.print((char)data);data=fis.read(); //IOException——文件读写异常}fis.close();catch(FileNotFoundException e){ //e.printStackTrace(); }catch(IOException e){ //(IOException是父类必须放到下面e.printStackTrace();}System.out.println("程序运行结束");
}
finally的使用(finally里面的语句必须执行,一般是流资源的关闭声明在finally中)
finally和catch是可以选择的,finally不可以单独使用,
什么样的代码必须声明在finally中呢?
我们在开发过程中finally中一些资源比如说(输入流,输出流,数据库连接,Socket连接的资源,在使用完后,必须显示的进行关闭操作,否则,GC不会自动的回收这些资源。进而导致内存泄漏)
public void test9()
{File file =new File("hello.txt");FileInputStream fis =new FileInputStream(file); //FileNotFoundException——文件没有找到int data =fis.read();//IOException——文件读写异常while(data !=-1){System.out.print((char)data);data=fis.read(); //IOException——文件读写异常}catch(FileNotFoundException e){ //e.printStackTrace(); }catch(IOException e){ //(IOException是父类必须放到下面e.printStackTrace();}//必须执行的语句finally{try{fis.close();
}
catch(IOException e)
{e.printStackTrace();
}
}}import org.junit.Test
public class FinallyTest{@Testpublic void test1(){//'NumberFormatException——数据格式输入异常'String str ="123";str ="abc";int i=Integer.parseInt(str); //把str转化为int类型int i=123System.out.println(i)}catch(NumberFormatException e){e.printStackTrace();}finally{System.out.println("程序结束"); }}
总结:
编译时的异常可以使用方式1,2处理,不推荐改代码
运行时的异常不推荐使用方式1,2处理,推荐改代码
方式二:throw+异常类型——(叫人)向山下叫人上来帮忙打狼,调用方法
格式:叫人,喊人
语法格式:throws 异常类型1,异常类型2,.........
public void test() throws 异常类型1,异常类型2
可以方法中嵌套,
public void Throws(){
public void method1() throws FileNotFoundException, IOException
{
File file =new File("D: \\hello.txt");
FileInputStream fis =new FileInpuntStream(file);int data =fis.read();
while(data!=-1){System.out.print((char)data);data =fis.read();
}fis.close(); }
}
开发中如何选择解决编译异常的方式(经验之谈)
有资源一定要被执行的:try-catch-finally
重写try-catch-finally
认识 Exception
Exception 位于 java.lang 包下,它是—种顶级接口,继承于 其子类都是 Throwable 的组成条件,是程序出现的合理情况。
在认识 Exception 之前,有必要先了解—下什么是 Throwable 。
什么是 Throwable——异常的根源类
Throwable 类是 Java 语言中所有 错误(errors) 和 异常(exceptions) 的父类。只有继承于
Throwable 的类或者其子类才能够被抛出,还有—种方式是带有 Java 中的 @throw 注解的类也可以 抛出。
在Java规范中,对非受查异常和受查异常的定义是这样的:
也就是说,除了 RuntimeException checkedException 。和其子类,其它的所有异常都是
那么,按照这种逻辑关系,我们可以对 Throwable 及其子类进行归类分析
可以看到, Throwable 位于异常和错误的最顶层,我们查看 Throwable 类中发现它的方法和属性有很 多,我们只讨论其中几个比较常用的
// 返回抛出异常的详细信息2 public string getMessage(); public string getLocalizedMessage();//返回异常发生时的简要描述6 public public String toString(); // 打印异常信息到标准输出流上9 public void printStackTrace(); public void printStackTrace(PrintStream s); public void printStackTrace(PrintWriter s)// 记录栈顿的的当前状态14 public synchronized Throwable fillInStackTrace();
此外,因为 Throwable 的父类也是 Object ,
所以常用的方法还有继承其父类的 getClass() 和 getName() 方法。**## 常见的 Exception
**
下面我们回到 Exception 的探讨上来,现在你知道了 Exception 的父类是 Throwable,并且 Exception 有两种异常, —种是 RuntimeException ;—种是 CheckedException ,这两种异常都应该去 捕 获 。
下面列出了—些 Java 中常见的异常及其分类,这块面试官也可能让你举出几个常见的异常情况并将其 分类
RuntimeException
UncheckedException
与 Exception 有关的 Java 关键字
那么 Java 中是如何处理这些异常的呢?在 Java 中有这几个关键字 throws 、throw 、try 、finally、 catch 下面我们分别来探讨一下
throws 和 throw
在 Java 中,异常也就是一个对象,它能够被程序员自定义抛出或者应用程序抛出,必须借助于 throws 和 throw 语句来定义抛出异常。
throws 和 throw 通常是成对出现的,例如
throw语句用在方法体内,表示抛出异常,由方法体内的语句处理。 throws 语句用在方法声明后面, 表示再抛出异常,由该方法的调用者来处理。
throws 主要是声明这个方法会抛出这种类型的异常,使它的调用者知道要捕获这个异常。 throw 是具 体向外抛异常的动作,所以它是抛出一个异常实例。
try 、finally 、catch
这三个关键字主要有下面几种组合方式 try…catch 、try…finally 、try…catch…finally 。
try…catch 表示对某一段代码可能抛出异常进行的捕获,如下
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3ef7f033b422400c9dfbe017dfff5688.png
try…catch…finally 也是—样的,表示对异常捕获后,再走 finally 中的代码逻辑。
什么是 Error
Error 是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作 无关,而表示代码运行时 JVM (Java 虚拟机)出现的问题。这些错误是不可检查的,因为它们在应用 程序的控制和处理能力之 外,而且绝大多数是程序运行时不允许出现的状况,比如
OutOfMemoryError 和 StackOverflowError 异常的出现会有几种情况,这里需要先介绍—下 Java 内存模型 JDK1.7。
其中包括两部分, 由所有线程共享的数据区和线程隔离的数据区组成,在上面的 Java 内存模型中, 只 有程序计数器是不会发生 OutOfMemoryError 情况的区域,程序计数器控制着计算机指令的分支、 循环、跳转、异常处理和线程恢复,并且程序计数器是每个线程私有的。
如果应用程序执行的是 Java 方法,那么这个计数器记录的就是 虚拟机字节码 指令的地址;如果正在执 行的是 Native 方法,这个计数器值则为 空(Undefined) 。
除了程序计数器外,其他区域: 方法区(Method Area) 、 虚拟机栈(VM Stack) 、 本地方法栈 (Native Method Stack) 和 堆(Heap) 都是可能发生 OutOfMemoryError 的区域。
虚拟机栈:如果线程请求的栈深度大于虚拟机栈所允许的深度,将会出现
StackOverflowError 异常;如果虚拟机动态扩展无法申请到足够的内存,将出现 OutOfMemoryError 。
本地方法栈和虚拟机栈一样
堆: Java 堆可以处于物理上不连续,逻辑上连续,就像我们的磁盘空间一样,如果堆中没有内存 完成实例分配,并且堆无法扩展时,将会抛出 OutOfMemoryError。
方法区:方法区无法满足内存分配需求时,将抛出 OutOfMemoryError 异常。
在 Java 中,你可以把异常理解为是一种能够提高你程序健壮性的机制,它能够让你在编写代码中注意 这些问题,也可以说,如果你写代码不会注意这些异常情况,你是无法成为一位硬核程序员的