java异常分类
java异常处理方法及流程
java异常处理方法及流程Java 异常处理方法及在 Java 编程中,异常处理是一项非常重要的技术。
通过适当的异常处理方法,可以使程序具备更好的稳定性和可读性,提高程序的健壮性。
本文将详细介绍 Java 异常处理的各个流程。
异常的基本概念异常是在程序执行期间产生的一种错误或异常情况。
Java 引入了异常处理机制来处理这些异常,以提高程序的可靠性和可维护性。
异常分为两种类型:1.受检异常(Checked Exceptions):受检异常在编译阶段必须进行处理,否则编译器将报错。
例如,IOException 是常见的受检异常。
2.非受检异常(Unchecked Exceptions):非受检异常是指不需要显式捕获或声明抛出的异常,编译器不会检查是否对其进行处理。
例如,NullPointerException 是常见的非受检异常。
异常处理的方法Java 提供了多种处理异常的方法,包括捕获异常和抛出异常。
下面分别进行介绍。
捕获异常是指通过使用try-catch语句块来捕获并处理异常。
try语句块用于包裹可能出现异常的代码,catch语句块用于捕获并处理异常。
try {// 可能抛出异常的代码块// ...} catch (ExceptionType1 e1) {// 处理异常类型1// ...} catch (ExceptionType2 e2) {// 处理异常类型2// ...} finally {// 可选的 finally 代码块,始终会被执行// ...}抛出异常当一个方法无法处理某个异常时,可以通过throw关键字手动抛出异常。
异常将会被传递给调用该方法的代码,并进一步处理。
public void someMethod() throws SomeException {if (someCondition) {throw new SomeException("Some error message");}使用异常的注意事项在使用异常处理时,需要注意以下几点:•捕获异常的顺序非常重要,应该从特定异常到一般异常的顺序进行捕获。
java中常见的五种异常
java中常见的五种异常
1.ClassCastException(类转换异常)
数据类型转换错误,比如有个String temp="abc"; 如果设为(int)temp就会报错了,因为它们类型不一样,但是设为(object)temp就可以,因为object是它们的父类
2.IndexOutOfBoundsException(数组越界)
这个异常我们在操作数组的时候会经常遇到,异常的解释是“数组下标越界“,现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。
3.NullPointerException(空指针)
这个异常在编程时也经常遇到,异常的解释是“程序遇上了空指针“,简单地说就是调用了未经初始化的对象或者是不存在的对象,这个错误经常出现在调用数组这些操作中,对数组操作中出现空指针,很多情况下是一些刚开始学习编程的人常犯的错误,即把数组。
Java异常——异常分类、声明检查型异常
Java异常——异常分类、声明检查型异常⼀、异常的分类1、在Java程序设计语⾔中,异常对象都是派⽣于Throwable类的⼀个类的实例。
如果Java的内置类不能满⾜需求,⽤户还可以创建⾃⼰的异常类。
2、异常分为两⽀,Error和Exception。
Error类层次描述了Java运⾏时系统的内部错误和资源耗尽错误。
这种情况很少出现,如果出现了这种情况,就只能通知⽤户并妥善地终⽌程序。
Exception类是应该重点关注的层次结构。
3、Exception类分解成两个分⽀:⼀⽀派⽣于RuntimeException,另⼀⽀派⽣于其他异常。
派⽣于RuntimeException的异常包括以下问题:“如果出现RuntimeException异常,那么⼀定是你的问题”☛错误的强制类型转换☛数组访问越界☛访问null指针不是派⽣于RuntimeException的异常包括以下问题:⼀般是I/O错误这类问题导致的☛试图超越⽂件末尾继续读取⽂件☛试图打开不存在的⽂件☛试图根据给定的字符串查找Class对象,⽽这个字符串表⽰的类不存在。
4、检查型异常和⾮检查型异常。
Java语⾔规范将派⽣于Error或RuntimeException类的所有异常称为⾮检查型异常(unchecked),所有其他类型的异常称为检查型异常(chcked)。
编译器会检查你是否为所有的检查型提供了异常处理器。
⼆、声明检查型异常public FileInputStream(String name)throws FileNotFoundException这个声明是标准类库中FileInputStream类的⼀个构造器的声明。
这个声明表⽰构造器根据给定的String参数产⽣⼀个FileInputStream对象,但也有可能抛出FileNotFoundException异常。
如果发⽣了糟糕的情况,构造器不会初始化⼀个新的FileInputStream对象,⽽是抛出⼀个FileNotFoundException类对象,如果抛出了这样⼀个异常对象,系统会开始搜索知道如何处理FileNotFoundException对象的异常处理器。
Java异常类型及处理
Java异常类型及处理⽬录⼀、异常定义⼆、异常的结构和分类三、异常的处理和捕获四、⾃定义异常五、异常的应⽤1.打印堆栈2.弹出流程六、注意点总结⼀、异常定义异常就是“意外、例外”的意思,也就是⾮正常情况。
异常本质上是程序上的错误,包括程序逻辑错误和系统错误。
异常的处理基本上就是⽤来兜底的,也是程序开发中程序不愿意看到的。
异常最基本的信息就是线程的堆栈信息。
⼆、异常的结构和分类Throwable主要分为Error和Exception。
错误:Error类以及他的⼦类的实例,代表了JVM本⾝的错误。
错误不能被程序员通过代码处理,躺平解决就好,不要反抗。
常见的错误有下⾯这些异常:Exception以及他的⼦类,代表程序运⾏时发送的各种不期望发⽣的事件。
可以被Java异常处理机制使⽤,是异常处理的核⼼,能在程序中解决的都不叫事。
常见的异常有这么多。
三、异常的处理和捕获异常想要处理肯定要先捕获到异常才可以,怎么捕获异常呐,Java给我提供了⼏个关键字,每个关键字怎么⽤呐?1、try,catch 就是直接捕获异常,catch 内的异常类型是能捕获的类型,⼀般如果有多个异常,从上到下的顺序是异常范围越来越⼤。
注:ErrorCodeException的定义可以参考⾃定义异常。
public static void second(String[] args) {try {throw new ErrorCodeException("1123");} catch (ErrorCodeException e) {e.printStackTrace();}catch (Exception e){e.printStackTrace();}}2、try catch finally 增加了finally关键字,就是在异常之后还能做⼀些事情,⽐如常见的关闭输⼊流,输出流,是程序最后的倔强。
public static String readFileContent(String fileName) {File file = new File(fileName);BufferedReader reader = null;StringBuffer sbf = new StringBuffer();try {reader = new BufferedReader(new FileReader(file));String tempStr;while ((tempStr = reader.readLine()) != null) {sbf.append(tempStr);}reader.close();return sbf.toString();} catch (IOException e) {e.printStackTrace();} finally {if (reader != null) {try {reader.close();} catch (IOException e1) {e1.printStackTrace();}}}return sbf.toString();}3、throw 主要⽤来创建⼀个异常,因为程序中可能需要抛出⼀个异常,⽐如我们游戏服务器游戏逻辑验证客户端参数不通过,会主动抛出⼀个⾃定义的异常4、throws 主要⽤在⽅法签名上,当我们读写⽂件或者反射的时候,如果不⽤try catch 就会发现⽅法签名后有⼀堆的异常需要处理。
java的异常处理机制名词解释
java的异常处理机制名词解释在Java开发过程中,异常处理机制是一项重要的功能。
它允许我们在程序中正确处理异常情况,使程序能够更加健壮。
本文将围绕Java的异常处理机制展开,逐步分析其中的名词解释。
1. 异常在Java中,异常指的是在程序执行过程中发生的一些错误或不正常的情况。
这些情况可能是由于用户输入的不正确或系统资源不足等原因所导致。
当程序发生异常时,程序流程将会被中断并转入异常处理程序进行处理。
2. 异常分类Java中的异常分为两类:受检异常和非受检异常。
受检异常是在编译期就可以检测到的异常,编译器强制要求程序去处理这些异常。
而非受检异常不需要强制要求程序去处理,通常是由程序逻辑错误引起的。
3. 异常处理器异常处理器是一段特殊的程序,用于捕获并处理异常。
在Java 中,异常处理器通常使用try-catch语句块来实现。
当程序执行到try 语句块时发生异常,程序将转入catch语句块并进行异常处理。
4. 抛出异常当程序执行发生异常时,可以使用throw语句抛出异常。
throw 语句通常包括一个异常对象,用于说明发生的异常类型。
5. 自定义异常在Java中,我们可以自定义异常来处理我们自己的异常情况。
自定义异常需要继承自Exception类或者RuntimeException类。
通过自定义异常,我们可以将一些通用的异常情况封装起来,提高程序的可读性和可维护性。
6. finally块finally块是try-catch语句块的可选部分,用于在无论是否发生异常都要执行的代码。
finally块通常用于释放资源或进行清理操作。
7. try-with-resources语句try-with-resources语句是Java 7中新增的语法,用于自动关闭资源。
这种语句会自动将在try语句块中声明的资源关闭,无需手动关闭。
这在程序中可以简化代码,提高程序的可读性和可维护性。
通过以上分步骤阐述,我们深入了解了Java的异常处理机制,并对其中的名词解释有了更加清晰的认识。
异常的定义和分类
异常的定义和分类
异常
异常分类:
Java中,异常对象都是派⽣于Throwable类的⼀个实例。
Java内置的异常类,不能满⾜需求,可以⾃⼰创建异常类
Throwable分成2个分⽀:Error和Exception。
Error 类描述了java运⾏时系统的内部错误和资源耗尽错误。
应⽤程序不应该抛出这样的错误。
Exception划分2个分⽀:⼀个分⽀派⽣于RuntimeException;另⼀个分⽀包含其他异常。
划分2个分⽀的规则是:由程序错误导致的异常属于RuntimeException;⽽程序本⾝没有问题,但由于像i/o错误这问题导致的异常属于其他异常。
派⽣于RuntimeException的异常包括:
错误的类转换。
数组访问越界。
访问空指针。
不是派⽣于RuntimeException的异常包括:
试图在⽂件尾部读取数据;
试图打开⼀个不存在的⽂件;
试图根据给定的字符串查找Class对象,⽽这个字符串对象不存在;
Java语⾔规范将派⽣于Error类和RuntimeExeption类的所有异常称为未检查(unchecked)异常,所有的其他的异常称为已检查(checked)异常。
编译器将核查是否,为所有的已检验异常提供了异常处理器。
总之,⼀个⽅法必须声明所有可能抛出的已检测的异常。
⽽未检查异常要么不可控制(Error),
要么就应该避免发⽣(RuntimeException);如果⽅法没有声明所有可能发⽣的已检查异常,编译器就会给出⼀个错误信息。
Java常见异常(RuntimeException)详细介绍并总结
Java常见异常(RuntimeException)详细介绍并总结本⽂重在Java中异常机制的⼀些概念。
写本⽂的⽬的在于⽅便我很长时间后若是忘了这些东西可以通过这篇⽂章迅速回忆起来。
1. 异常机制1.1 异常机制是指当程序出现错误后,程序如何处理。
具体来说,异常机制提供了程序退出的安全通道。
当出现错误后,程序执⾏的流程发⽣改变,程序的控制权转移到异常处理器。
1.2 传统的处理异常的办法是,函数返回⼀个特殊的结果来表⽰出现异常(通常这个特殊结果是⼤家约定俗称的),调⽤该函数的程序负责检查并分析函数返回的结果。
这样做有如下的弊端:例如函数返回-1代表出现异常,但是如果函数确实要返回-1这个正确的值时就会出现混淆;可读性降低,将程序代码与处理异常的代码混爹在⼀起;由调⽤函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解。
1.3 异常处理的流程1.3.1 遇到错误,⽅法⽴即结束,并不返回⼀个值;同时,抛出⼀个异常对象1.3.2 调⽤该⽅法的程序也不会继续执⾏下去,⽽是搜索⼀个可以处理该异常的异常处理器,并执⾏其中的代码2 异常的分类2.1 异常的分类2.1.1 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception,具体的RuntimeException继承RuntimeException。
2.1.2 Error和RuntimeException及其⼦类成为未检查异常(unchecked),其它异常成为已检查异常(checked)。
2.2 每个类型的异常的特点2.2.1 Error体系 Error类体系描述了Java运⾏系统中的内部错误以及资源耗尽的情形。
应⽤程序不应该抛出这种类型的对象(⼀般是由虚拟机抛出)。
如果出现这种错误,除了尽⼒使程序安全退出外,在其他⽅⾯是⽆能为⼒的。
Java的throw和throws
catch (Exception e)
{
System.out.println("catch块处理了Rutime异常");
}
}
public static void main(String[] rags)
{
new A().set();
}
}
2、不做任何处理(即交给Java虚拟机处理,处理结果:打印异常跟踪栈信息后终止程序运行),如下文的例子三就没有处理。
1、用try{} catch{}捕获处理抛出的异常,如下class A:
class A
{ void setFra bibliotek) {
try
{
// 抛出一个Runtime异常
// new RuntimeException():构造一个详细信息为null的新运行时异常实例
throw new RuntimeException();
情况二:如果抛出的是Checked异常,则必须处理,也有两种处理方式:=====================================情况二
1、调用抛出了异常的方法时,将这个方法调用语句放入try块中显式捕获该异常,如下文的例子一;
2、将调用这个方法(抛出了异常的方法)的方法用throws声明抛出异常,如下文的例子二。
例子三:throw语句抛出Runtime异常,所在方法可以不理会,不抛出异常==========================================例子三(class D)
import javax.swing.JOptionPane;
class D
{
void set()//-------------与例子二不同处,可以不声明抛出,不做异常处理
Java运行时异常和受检异常区别解析
Java运行时异常和受检异常区别解析Java是一种广泛使用的编程语言,具有强大的异常处理机制。
在Java中,异常分为运行时异常和受检异常两种类型。
这两种异常在语法上有所不同,也有不同的处理方式和使用场景。
本文将深入探讨Java运行时异常和受检异常的区别,并分析它们的特点和应用。
1. 异常的概念和分类在编程中,异常是指程序运行过程中可能发生的错误或异常情况。
Java中的异常分为两种类型:运行时异常和受检异常。
运行时异常是指在程序运行过程中可能出现的错误,但不需要在代码中显式地处理。
这些异常通常是由程序员的错误或逻辑问题引起的,如除零错误、空指针引用等。
运行时异常的典型特点是它们是RuntimeException类或其子类的实例。
受检异常是指在程序运行过程中可能出现的错误,但必须在代码中显式地处理。
这些异常通常是由外部因素引起的,如文件读取错误、网络连接问题等。
受检异常的典型特点是它们是Exception类或其子类的实例,但不是RuntimeException类的子类。
2. 运行时异常的特点和使用场景运行时异常具有以下特点:- 运行时异常不需要在代码中显式地处理,可以选择捕获和处理,也可以不处理。
- 运行时异常通常是由程序员的错误或逻辑问题引起的,如数组越界、类型转换错误等。
- 运行时异常的出现通常意味着代码存在缺陷或错误,需要程序员进行修复。
运行时异常的使用场景包括:- 在开发过程中,如果发现代码中存在逻辑错误或潜在的异常情况,可以使用运行时异常来表示并抛出。
- 运行时异常也可以用于简化代码逻辑,使代码更加简洁和易读。
3. 受检异常的特点和使用场景受检异常具有以下特点:- 受检异常必须在代码中显式地处理,要么通过try-catch语句捕获和处理,要么通过throws关键字声明抛出。
- 受检异常通常是由外部因素引起的,如文件读取错误、网络连接问题等。
- 受检异常的出现通常意味着程序需要采取一些措施来处理外部因素的影响,保证程序的正常运行。
常见的几种异常类型Exception
常见的⼏种异常类型Exception 常见异常类型:Java中的异常分为两⼤类:1.Checked Exception(⾮Runtime Exception) 2.Unchecked Exception(Runtime Exception)算数异常类:ArithmeticExecption空指针异常类型:NullPointerException类型强制转换类型:ClassCastException数组负下标异常:NegativeArrayException数组下标越界异常:ArrayIndexOutOfBoundsException违背安全原则异常:SecturityException⽂件已结束异常:EOFException⽂件未找到异常:FileNotFoundException字符串转换为数字异常:NumberFormatException操作数据库异常:SQLException输⼊输出异常:IOException⽅法未找到异常:NoSuchMethodException下标越界异常:IndexOutOfBoundsExecption系统异常:SystemException创建⼀个⼤⼩为负数的数组错误异常:NegativeArraySizeException数据格式异常:NumberFormatException安全异常:SecurityException不⽀持的操作异常:UnsupportedOperationException⽹络操作在主线程异常:NetworkOnMainThreadException请求状态异常: IllegalStateException (extends RuntimeException ,⽗类:IllegalComponentStateException在不合理或不正确时间内唤醒⼀⽅法时出现的异常信息。
换句话说,即 Java 环境或 Java 应⽤不满⾜请求操作)⽹络请求异常:HttpHostConnectException⼦线程Thread更新UI view 异常:ViewRootImpl$CalledFromWrongThreadException证书不匹配的主机名异常: SSLExceptionero反射Method.invoke(obj, args...)⽅法抛出异常:InvocationTargetExceptionEventBus使⽤异常:EventBusException⾮法参数异常:IllegalArgumentException参数不能⼩于0异常:ZeroException。
Java中异常的概念和分类
Java中异常的概念和分类
异常就是程序在编译时发⽣的意想不到的情况,⼀般⽽⾔分为两类:错误(Error)和异常(Exception)
Error: 分为两种:
程序编写出现语法错误
Exception: 所有异常类的⽗类(我们说的异常处理⼀般就是处理与Exception类相关的异常,Exception和Error合起来被称作异常,但Exception⾃⾝也可以被称为异常,通常我们说的异常指的就是Exception及其⼦类
Exception异常分为编译时异常和运⾏时异常,由于我们⽆法预测程序⾥可能出现的错误或⽤户在使⽤程序时会出现的错误,所以需要异常类来告诉我们程序出现了异常,⽐如0不能作为除数,但⽤户硬是⽤做了除数怎么办?
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
System.out.println(1/a);
}
Exception的⼦类被分为两⼤类:编译时异常,运⾏时异常
编译时异常: 在编写代码时如果有此类异常则必须被捕获(catch)或抛出(throw)
运⾏时异常: 可以不必再编写代码时捕获或抛出
说明: 所有异常都可以被捕获或抛出,如果异常最终没有被捕获⽽是被抛出的话程序会⽴即终⽌运⾏并打印异常信息,另外,如果不捕获运⾏时异常,默认会抛出运⾏时异常
编译时异常的特征: 直接继承⾃Exception类,不继承RuntimeException,必须被显式的捕获或抛出
运⾏时异常的特征: 继承⾃RuntimeException类,可以不被显式的捕获或抛出,如果不被显式的捕获则默认会被抛出。
java异常--throwable和exception
java异常--throwable和exceptionJava设置了异常,旨在⿎励将⽅法中可能出现的异常告知给使⽤此⽅法的程序员(你和我!)。
当然了,这种⽅法是⽐较优雅的,让我们确切的知道是在哪⾥出了错,并提供了异常捕获。
本篇⽂章主要对Java中的异常进⾏介绍与区分。
先上⼀张类图这是异常的类图。
Throwable是Error和Exception的⽗类,⽤来定义所有可以作为异常被抛出来的类。
Error和Exception区分:Error是编译时错误和系统错误,系统错误在除特殊情况下,都不需要你来关⼼,基本不会出现。
⽽编译时错误,如果你使⽤了编译器,那么编译器会提⽰。
Exception则是可以被抛出的基本类型,我们需要主要关⼼的也是这个类。
Exception⼜分为RunTimeException和其他Exception。
RunTimeException和其他Exception区分:1. 其他Exception,受检查异常。
可以理解为错误,必须要开发者解决以后才能编译通过,解决的⽅法有两种,1:throw到上层,2,try-catch处理。
2. RunTimeException:运⾏时异常,⼜称不受检查异常,不受检查!不受检查!!不受检查重要的事情说三遍,因为不受检查,所以在代码中可能会有RunTimeException时Java编译检查时不会告诉你有这个异常,但是在实际运⾏代码时则会暴露出来,⽐如经典的1/0,空指针等。
如果不处理也会被Java⾃⼰处理。
---------执⾏结果 ---------1运⾏结果是1,为什么呢?主函数调⽤⼦函数并得到结果的过程,好⽐主函数准备⼀个空罐⼦,当⼦函数要返回结果时,先把结果放在罐⼦⾥,然后再将程序逻辑返回到主函数。
所谓返回,就是⼦函数说,我不运⾏了,你主函数继续运⾏吧,这没什么结果可⾔,结果是在说这话之前放进罐⼦⾥的。
2.下⾯的程序代码输出的结果是多少?public class smallT{public static void main(String args[]){smallT t = new smallT();int b = t.get();System.out.println(b);}public int get(){try {return 1;}finally{return 2;}}}返回的结果是2。
Java里的异常(Exception)详解
Java⾥的异常(Exception)详解作为⼀位初学者, 本屌也没有能⼒对异常谈得很深⼊. 只不过⾥关于Exception的东西实在是很多. 所以这篇⽂章很长就是了..⼀, 什么是java⾥的异常由于java是c\c++ 发展⽽来的, ⾸先我们先看看c语⾔⾥的错误.1.1 c语⾔⾥的错误我们实现1个程序的过程包括, 代码编写, 编译代码成为程序, 执⾏程序..其中⼤部分常见的语法错误都会被编译代码这样部过滤掉. 但是即使通过了编译. 执⾏程序这⼀步可能还是会有错误.原因很多, 例如常见的除数为0, 内存溢出(数组的index超出界限), 或者内存被其他程序修改等.最简单的例⼦:[java]1. #include <stdio.h>2.3. int f(int a, int b){4. return a/b;5. }6.7. int main(){8. int i = f(8,0);9. printf("i is %d\n",i);10. return 0;11. }上⾯的例⼦编译时是⽆错的, 但是⼀旦执⾏就会提⽰吐核错误了.c语⾔⾥对这种执⾏时出现的错误是⽆能为⼒的, ⼀旦出错就会整个程序崩溃, 就不会在继续执⾏下⾯的代码.⽽且很多时候出错信息很少, 让你⽆法判断出错的原因和地⽅, 只能⼀步步⼩⼼debug...所以很多⽤c写的程序有时会出现⾮法关闭的现象.解决⽅法只能是在代码⾥对可能出错的地⽅添加if 判断.例如f()函数⾥可以对b进⾏判断, 如果是0就不执⾏.1.2 java⾥运⾏时出现的错误java⾥编译器对代码的规范性⽐c严格得多. 但是即使如此, 通过编译的java程序有时也很难避免执⾏时出错.例如, 将上⾯的c程序改编成java程序:[java]1. package Exception_kng;2.3. class Exp1{4. public int f(int a, int b){5. return a/b;6. }7. }8.9. public class Expt_1{10. public static void g(){11. Exp1 e = new Exp1();12. int i = e.f(8,0);13. System.out.printf("i is %d\n", i);14. }15. }运⾏时⼀样会出错, 下⾯是出错信息:[java]1. [java] Caused by: ng.ArithmeticException: / by zero2. [java] at Exception_kng.Exp1.f(Expt_1.java:5)3. [java] at Exception_kng.Expt_1.g(Expt_1.java:12)4. [java] at Enter_1.main(Enter_1.java:31)但是可以见到, java告诉你出错的类型: 运算错误(ArithmeticExcetion), 出错信息和出错的类与⽂件⾏数输出, ⽅便你调试. jvm虚拟机是会对错误作出⼀定的处理的.所以可以简单地将java⾥的异常理解成java运⾏时出现的错误, 异常机制就是对这种错误进⾏处理的机制.1.3 java异常的定义实际上, 当java程序执⾏时出现错误时, jvm会把执⾏时出错的信息(例如出错原因, 类型, 位置) 收集,然后打包成为1个对象(object), 程序员可以对这种对象进⾏处理. 这种对象就是所谓的异常.可能出现的异常的代码并不是肯定会出现异常, 取决于执⾏环境和数据.!⼆, java⾥的异常的分类.见下图:Throwable/ \Error Exception/ / \xxxxxx xxxxxx RuntimeException/ \xxxxxx ArithmeticException上图的所有对象都是类.Throwable 代表是可抛出的.Error 代表的是严重错误, 这种错误程序员⽆法进⾏处理, 例如操作系统崩溃, jvm出错, 动态链接库失败等. Error并不是异常, 不是本⽂的重点.Exception 代表的就是异常了. 它下⾯很多派⽣类, 其中它的派⽣类也分两种, ⼀种是RuntimeException(运⾏时异常), 其他的都是⾮运⾏时异常RuntimeException 包括除数为0, 数组下标超界等. 运⾏时异常的派⽣类有很多, 其产⽣频率较⾼. 它的派⽣类可以由程序处理或者抛给(throw) 给jvm处理. 例如上⾯的例⼦就是抛给了jvm处理, jvm把程序中断执⾏, 并把错误信息输出到终端上.⾮RuntimeExcption 这种异常属于Excepion的派⽣类(上⾯红⾊的xxx), 但是不是RuntimeException的派⽣类, 这种异常必须由程序员⼿动处理,否则不通过编译.ArithmeticExcpetion 算术异常, 它是RuntimeException的派⽣类, 所以程序员不⼿动处理也通过编译, 只不过出错时会被jvm处理.三, java⾥对异常的处理java⾥对异常的处理有三种.3.1 程序猿对有可能出现的异常使⽤try catch处理.例如我们将上⾯的例⼦改动⼀下:[java]1. package Exception_kng;2.3. class Exp2{4. public int f(int a, int b){5. int i = 0;6. try{7. i = a/b;8. }9. catch(Exception e){10. System.out.printf("Exception occurs!!\n");11. System.out.println(e.getMessage()); //print the root cause12. System.out.printf("===========================\n");13. e.printStackTrace(); //print the info of function stuck.14. }15.16. return i;17. }18. }19.20. public class Expt_2{21. public static void g(){22. Exp2 ex = new Exp2();23. int i = ex.f(8,0); //call f()24. System.out.printf("i is %d\n", i); //successfully executed25. }26. }在f()函数中对可能出现的异常的代码进⾏try catch处理后, 程序会执⾏catch⾥的代码. ⽽且不会中断整个程序, 继续执⾏try catch后⾯的代码.程序执⾏输出:[java]1. [java] Exception occurs!!2. [java] / by zero3. [java] ===========================4. [java] ng.ArithmeticException: / by zero5. [java] at Exception_kng.Exp2.f(Expt_2.java:7)6. [java] at Exception_kng.Expt_2.g(Expt_2.java:23)7. [java] at Enter_1.main(Enter_1.java:31)8. [java] i is 0注意最终也执⾏了g()函数中的最后⼀条语句, 输出了i的值.也就是说try catch处理后并不会终⽌程序, 令程序即使出现了错误, 也可以对错误进⾏⼀定的处理后继续执⾏. 这就是java异常机制⽐c语⾔安全的地⽅.下⾯会详细讲解 try catch.注:getMessage() ⽅法: Exception类的⽅法之⼀, 返回异常的原因, 上⾯的 / by zero 就是这个⽅法输出的.printStackTrace(): Exception类的⽅法之⼀, 在屏幕输出函数栈信息, 也就是异常出现的地⽅.3.2 函数⾥并不处理异常, 使⽤throw or throws 关键字把可能出现的异常抛给调⽤该函数的上级函数处理.例如我在f()函数中不想处理可能出现的异常, 想把它抛出上级函数处理:下⾯是个例⼦:[java]1. package Exception_kng;2.3. class Exp3{4. public int f(int a, int b){5. if (0 == b){6. throw new ArithmeticException("Shit !!! / by zero!");7.8. }9.10. return a/b;11. }12. }13.14. public class Expt_3{15. public static void g() throws ArithmeticException{16. Exp3 ex = new Exp3();17. int i = 22;18. i = ex.f(8,0); //throw excetpion19. System.out.printf("i is %d\n", i); //failed executed20. System.out.printf("g() is done!!\n"); //failed executed21. }22.23. public static void h(){24. try{25. g();26. }catch(ArithmeticException e){27. System.out.printf("Exception occurs!!\n");28. System.out.println(e.getMessage()); //print the root cause29. System.out.printf("===========================\n");30. e.printStackTrace(); //print the info of function stuck.31. }32.33. System.out.printf("h() is done!!\n"); //successfully executed34. }35. }可以见到f() 加了个条件判断, 如果参数b = 0, 使⽤throw 直接⼿动抛出1个异常. 让调⽤它的函数处理.g()调⽤f()函数, 预见到f()可能有异常, 但是也不想处理, 使⽤throws 关键字告诉调⽤它的函数本函数有可能抛出这种异常. // 注, 这⾥的throws 对程序并没有实质的影响.h()调⽤g(), 简单g()定义的throws, ⽤try catch在本函数进⾏处理.输出:[java]1. [java] Exception occurs!!2. [java] Shit !!! / by zero!3. [java] ===========================4. [java] ng.ArithmeticException: Shit !!! / by zero!5. [java] at Exception_kng.Exp3.f(Expt_3.java:6)6. [java] at Exception_kng.Expt_3.g(Expt_3.java:18)7. [java] at Exception_kng.Expt_3.h(Expt_3.java:25)8. [java] at Enter_1.main(Enter_1.java:31)9. [java] h() is done!!注意这个程序没有执⾏g() 最后的代码.throw 和 throws 后⾯也会详细讲解.3.3 交给jvm虚拟机处理假如上⾯的例⼦h() 也不处理怎么办? 就如1.2 的例⼦, 会抛给jvm处理.但是这种情况只适⽤于RuntimeExecption及其派⽣类.jvm怎么处理呢, 就是中断整个程序, 并把异常信息输出到屏幕上.实际上, 当java程序的1个函数抛出异常时,⾸先会检查当前函数有没有try catch处理, 如果⽆检查上⼀级函数有⽆try..catch处理....这样在函数栈⾥⼀级⼀级向上检查, 如果直⾄main函数都⽆try..catch, 则抛给jvm..项⽬中强烈建议尽量⼿动处理, 不要把异常交给jvm.四,Try catch finally 的处理机制.这⾥开始详解try catch finally了.语法是这样的.try{可能出异常的若⼲⾏代码;}catch(ExceptionName1 e){产⽣ExceptionName 1的处理代码;}catch(ExceptionName2 e){产⽣ExceptionName 2的处理代码;}...finally{⽆论如何, 最终肯定会执⾏的代码}4.1 try catch finally的执⾏路线.下⾯⽤个例⼦来说明:[java]1. try{2. f();3. ff();4. }5. catch(ArithmeticException e){6. g();7. }8. catch(IOException e){9. gg();10. }11. catch(AuthorizedException e){12. ggg();13. }14. finally{15. h();16. }17.18. k();4.1.1 当try⾥⾯的f()抛出了IOException当f()抛出了异常, 那么ff()就不会执⾏了. 程序会尝试捕捉异常.⾸先捕捉ArithmeticException, 捕捉失败.接下来捕捉IOException, 捕捉成功, 执⾏gg();⼀旦捕捉到⼀个异常, 不会再尝试捕捉其他异常, 直接执⾏finally⾥的h();执⾏后⾯的函数k().也就是说路线是:f() -> gg() -> h() -> k()有2点要注意的.1. f()函数极有可能未完整执⾏, 因为它抛出了异常, 抛出异常的语句执⾏失败, 之后的语句放弃执⾏.2. try{} ⾥⾯, f()之后的语句, 例如ff()放弃执⾏.4.1.2 没有任何异常抛出这种情况很简单, 就是try{}⾥⾯的代码被完整执⾏, 因为没有抛出任何异常, 就不会尝试执⾏catch⾥的部分, 直接到finally部分了.路线是:f() -> ff() -> h() -> k()4.2 如何确定要捕捉的异常名字.也许有⼈会问, 我们怎么知道到底会抛出什么异常?下⾯有3个解决⽅案.1.看代码凭经验, 例如看到1段除法的代码, 则有可能抛出算术异常.2.在catch的括号⾥写上Exception e, 毕竟Exception 是所有其他异常的超类, 这⾥涉及多态的知识, ⾄于什么是多态可以看看本⼈的另⼀篇⽂章.3. 观察被调⽤函数的函数定义, 如果有throws后缀, 则可以尝试捕捉throws 后缀抛出的异常4.3 为什么需要finally包括我在内很多⼈会觉得finally语句简直多勾余, 既然是否捕捉到异常都会执⾏, 上⾯那个例⼦⾥的h()为什么不跟下⾯的k() 写在⼀起呢.上⾯的例⼦的确看不出区别.但下⾯两种情况下就体现了finally独特的重要性.4.3.1 抛出了1个异常, 但是没有被任何catch⼦句捕捉成功.例如try⾥⾯抛出了1个A异常, 但是只有后⾯只有捕捉B异常, 和C异常的⼦句.这种情况下, 程序直接执⾏finally{}⾥的⼦句, 然后中断当前函数, 把异常抛给上⼀级函数, 所以当前函数finally后⾯的语句不会被执⾏.例⼦:[java]1. package Exception_kng;2.3. import .*;4. import java.io.*;5.6. class Exp4{7. public int f(int a, int b) throws IOException, BindException{8. return a/b;9. }10. }11.12. public class Expt_4{13. public static void g(){14. Exp4 ex = new Exp4();15. int i = 22;16. try{17. System.out.printf("g() : try!!\n"); //failed18. i = ex.f(8,0); //call f()19. }20. catch(BindException e){21. System.out.printf("g() : BindException!!\n"); //failed22. }23. catch(IOException e){24. System.out.printf("g() : IOException!!\n"); //failed25. }26. finally{27. System.out.printf("g() : finaly!!\n"); //successfully executed28. }29. System.out.printf("g() is done!!\n"); //failed30. }31.32. public static void h(){33. try{34. g();35. }catch(ArithmeticException e){36. System.out.printf("Exception occurs!!\n");37. System.out.println(e.getMessage()); //print the root cause38. System.out.printf("===========================\n");39. e.printStackTrace(); //print the info of function stuck.40. }41.42. System.out.printf("h() is done!!\n"); //successfully executed43. }44. }我所说的情况, 就在上⾯例⼦⾥的g()函数, g()函数⾥尝试捕捉两个异常, 但是抛出了第3个异常(ArithmeticException 算术异常).所以这个异常会中断g()的执⾏, 因为没有被捕捉到, 然后抛给调⽤g()的 h()函数处理, ⽽在h()捕捉到了, 所以h()函数是能完整执⾏的.也就是说g()⾥的[java]1. System.out.printf("g() is done!!\n"); //failed执⾏失败⽽h()⾥的[java]1. System.out.printf("h() is done!!\n"); //successfully executed执⾏成功但是⽆论如何, g()⾥的finally{}部分还是被执⾏了执⾏结果如下:[java]1. [java] g() : try!!2. [java] g() : finaly!!3. [java] Exception occurs!!4. [java] / by zero5. [java] ===========================6. [java] ng.ArithmeticException: / by zero7. [java] at Exception_kng.Exp4.f(Expt_4.java:8)8. [java] at Exception_kng.Expt_4.g(Expt_4.java:18)9. [java] at Exception_kng.Expt_4.h(Expt_4.java:34)10. [java] at Enter_1.main(Enter_1.java:31)11. [java] h() is done!!这种情况是1中编程的低级错误, 在项⽬中是不允许出现.避免⽅法也⼗分简单, 在catch⼦句集的最后增加1个catch(Exception e)就ok, 因为Exception是所有异常的超类, 只要有异常抛出, 则肯定会捕捉到.4.3.2 在catch⼦句内有return⼦句.下⾯例⼦:[java]1. try{2. f();3. ff();4. }5. catch(ArithException e){6. g();7. return j();8. }9. catch(IOException e){10. gg();11. return j();12. }13. catch(AuthorizedException e){14. ggg();15. return j();16. }17. finally{18. h();19. }20.21. k();假如在f()函数抛出了IOExcepion 异常被捕捉到.那么执⾏路线就是f() -> gg() -> j() -> h() -> 上⼀级function也就说, 这种情况下finally⾥的⼦句会在return回上⼀级function前执⾏. ⽽后⾯的k()就被放弃了.4.3.3 finally作⽤⼩结.可以看出, finally⾥的语句, ⽆论如何都会被执⾏.⾄有两种情况除外, ⼀是断电, ⼆是exit函数.在项⽬中, 我们⼀般在finally编写⼀些释放资源的动作, 例如初始化公共变量. 关闭connections, 关闭⽂件等.4.4 try catch finally⾥⼀些要注意的问题.4.4.1 ⽆论如何最多只有1个catch被执⾏这个上⾯提到过了, ⼀旦捕捉到1个异常, 就不会尝试捕捉其他异常.如果try⾥⾯的⼀段代码可能抛出3种异常A B C,⾸先看它先抛出哪个异常, 如果先抛出A, 如果捕捉到A, 那么就执⾏catch(A)⾥的代码. 然后finally.. B和C就没有机会再抛出了.如果捕捉不到A, 就执⾏finally{}⾥的语句后中断当前函数, 抛给上⼀级函数...(应该避免)4.4.2 有可能所有catch都没有被执⾏两种情况, 1就是没有异常抛出, 另⼀种就是抛出了异常但是没有捕捉不到(应该避免)4.4.3 先捕捉⼦类异常, 再捕捉⽗类异常, 否则编译失败加⼊try ⾥⾯尝试捕捉两个异常, 1个是A, 1个是B, 但是A是B的⽗类.这种情况下, 应该把catch(B)写在catch(A)前⾯.原因也很简单, 加⼊把catch(A)写在前⾯, 因为多态的存在, 即使抛出了B异常, 也会被catch(A)捕捉, 后⾯的catch(B)就没有意义了.也就是说如果捕捉Exception这个异常基类, 应该放在最后的catch⾥, 项⽬中也强烈建议这么做, 可以避免上述4.3.1的情况出现.4.4.4 catch与catch之间不能有任何代码.这个没什么好说的. 语法规则4.4.5 finally⾥不能访问catch⾥捕捉的异常对象e每1个异常对象只能由catch它的catch⼦句⾥访问.4.4.6 try⾥⾯的定义变量不能在try外⾯使⽤.跟if类似, 不多说了.4.4.7 try catch finally可以嵌套使⽤.这个也不难理解..五, throw 和throws的机制和⽤法.下⾯开始详讲异常另⼀种处理⽅法throw 和 throws了.注意的是, 这两种⽤法都没有真正的处理异常, 真正处理的异常⽅法只有try catch, 这两种⽅法只是交给上⼀级⽅法处理.就如⼀个组织⾥ , 有1个⼤佬, 1个党主, 1个⼩弟.⼤佬叫党主⼲活, 堂主叫⼩弟⼲活, 然后⼩弟碰上⿇烦了, 但是⼩弟不会处理这个⿇烦, 只能中断⼯作抛给党主处理, 然后堂主发现这个⿇烦只有⼤佬能处理, 然后抛给⼤佬处理..道理是相通的..5.1 throw 的语法与作⽤throws的语法很简单.语法:throw new XException();其中xException必须是Exception的派⽣类.这⾥注意throw 出的是1个异常对象, 所以new不能省略作⽤就是⼿动令程序抛出1个异常对象.5.2 throw 1个 RuntimeException及其派⽣类我们看回上⾯3.2 的例⼦:[java]1. public int f(int a, int b){2. if (0 == b){3. throw new ArithmeticException("Shit !!! / by zero!");4.5. }6.7. return a/b;8. }5.2.1 throw会中断当前函数, 当前函数执⾏失败(不完整)当这个函数的if 判断了b=0时, 就利⽤throws⼿动抛出了1个异常. 这个异常会中断这个函数. 也就是说f()执⾏不完整, 是没有返回值的.5.2.2, 接下来哪个调⽤这个函数就会在调⽤这个函数的语句上收到异常.[java]1. public void g(){2. int i;3. h();4. i = f(); //recevie excepton5. k();6. }例如上没的g()函数, 在调⽤f() 会收到1个异常.这时g()函数有三种选择.1. 不做任何处理这时, g()收到f()⾥抛出的异常就会打断g()执⾏, 也就是说g()⾥⾯的k(); 被放弃了, 然后程序会继续把这个函数抛给调⽤g()函数.然后⼀级⼀级寻求处理, 如果都不处理, 则抛给jvm处理. jvm会中断程序, 输出异常信息. 这个上没提到过了.2. 使⽤try catch处理如果catch成功, 则g()函数能完整执⾏, ⽽且这个异常不会继续向上抛.如果catch失败(尽量避免), 则跟情况1相同.5.3 throw 1个⾮RuntimeException派⽣类的异常将上⾯的例⼦改⼀下:[java]1. public int f(int a, int b){2. if (0 == b){3. throw new IOException("Shit !!! / by zero!");4. }5.6. return a/b;7. }例如, 我不想抛出ArithmeticException, 我想抛出IOExcetpion.注意这⾥, IOException虽然逻辑上是错误的(完全不是IO的问题嘛), 但是在程序中完全可⾏, 因为程序猿可以根据需要控制程序指定抛出任何1个异常.但是这段代码编译失败, 因为IOException 不是 RuntimeException的派⽣类.java规定:5.3.1 如果⼀个⽅法⾥利⽤throw⼿动抛出1个⾮RuntimeException异常, 必须在函数定义声明⾥加上throws 后缀改成这样就正确了:[java]1. public int f(int a, int b) throws IOException{2. if (0 == b){3. throw new IOException("Shit !!! / by zero!");4. }5.6. return a/b;7. }注意在⽅法定义⾥加上了throws⼦句. 告诉调⽤它的函数我可能抛出这个异常.5.3.2 调⽤该⽅法的⽅法则必须处理这个异常例如抄回上⾯的例⼦, g()调⽤f()函数.[java]1. public void g(){2. int i;3. h();4. i = f(); //recevie excepton5. k()6. }但是编译失败.因为f()利⽤throws 声明了会抛出1个⾮runtimeExcetpion. 这时g()必须做出处理.处理⽅法有两种:1. try catch⾃⼰处理:[java]1. public void g(){2. int i = 0;3. h();4. try{5. i = f(); //recevie excepton6. }7. catch(IOException e){8.9. }10. k();11. }需要注意的是, catch⾥⾯要么写上throws对应的异常(这⾥是 IOException), 要么写上这个异常的超类, 否则还是编译失败.2.g()利⽤throws 往上⼀级⽅法抛.[java]1. public void g() throws IOException{2. int i = 0;3. h();4. i = f(); //recevie excepton5. k();6. }这是调⽤g()的函数也要考虑上⾯的这两种处理⽅法了...但是最终上级的⽅法(main ⽅法)还是不处理的话, 就编译失败, 上⾯说过了, ⾮runtimeException⽆法抛给jvm处理.虽然这两种处理⽅法都能通过编译, 但是运⾏效果是完全不同的.第⼀种, g()能完整执⾏.第⼆种, g()被中断, 也就是g()⾥⾯的k(); 执⾏失败.5.4 throws 的语法.throws稍微⽐throw难理解点:语法是:public void f() throws Exception1, Exception2...{}也就是讲, thorws可以加上多个异常, 注意这⾥抛出的不是对象, 不能加上new.⽽且不是告诉别⼈这个函数有可能抛出这么多个异常. ⽽是告诉别⼈, 有可能抛出这些异常的其中⼀种.5.5 throws 的作⽤.如果为f()函数加上throws后续, 则告诉调⽤f()的⽅法, f()函数有可能抛出这些异常的⼀种.如果f()throws 了1个或若⼲个⾮RuntimeException, 则调⽤f()的函数必须处理这些⾮RuntimeException, 如上⾯的g()函数⼀样.如果f() throws的都是RuntimeException, 则调⽤f()的函数可以不处理, 也能通过编译, 但是实际上还是强烈建议处理它们.实际上, 如果1个⽅法f() throws A,B那么它有可能不抛出任何异常.(程序运⾏状态良好)也有能抛出C异常(应该避免, 最好在throws上加上C)5.6 什么时候应该⽤throws5.6.1 ⼀个函数体⾥⾯⼿动throw了1个RumtimeException, 则这个函数的定义必须加上throws⼦句这个是强制, 告诉别⼈这个函数内有炸弹.5.6.2 ⼀个函数内有可能由系统抛出异常.这个是⾮强制的, 但是如果你知道⼀个函数内的代码有可能抛出异常, 最好还是写上throws 后缀⽆论这个异常是否runtimeExcepion.5.7 ⼀般情况下,调⽤1个带有throws⽅法时怎么办个⼈建议, 如果你调⽤1个函数throws A, B, C那么你就在当前函数写上catch(A)catch(B)catch(C)catch(Exception)这样能处理能保证你的函数能完整执⾏, 不会被收到的异常中断.当然如果你允许你的函数可以被中断, 那么就可以在当前函数定义加上throws A, B 继续抛给上⼀级的函数.5.8 重写⽅法时, throws的范围不能⼤于超类的对应⽅法.例如你在⼀个派⽣类重写⼀个⽅法f(), 在超类⾥的f() throws A, B 你重写⽅法时就不throws出 A,,B,C 或者throws A和B的超类.原因也是由于多态的存在.因为1个超类的引⽤可以指向1个派⽣类的对象并调⽤不同的⽅法. 如果派⽣类throws的范围加⼤那么利⽤多态写的代码的try catch就不再适⽤.六, throw和throws⼀些主要区别.⾯试问得多,单独拉出来写了:6.1 throw 写在函数体内, throws写在函数定义语句中.应付⾯试官.6.2 throw 是抛出1个异常对象, throws是有能抛出异常的种类所以throw后⾯的⼀般加上new 和exception名字().⽽throws后⾯不能加上new的6.3 ⼀个⽅法最多只能throw1个异常, 但是可以throws多个种类异常因为⼀旦⼀个函数throw出1个异常, 这个函数就会被中断执⾏, 后⾯的代码被放弃, 如果你尝试在函数内写两个throw, 编译失败.⽽throws 是告诉别⼈这个函数有可能抛出这⼏种异常的⼀种. 但是最多只会抛出⼀种.6.4 如果在⼀个函数体内throw 1个⾮runtimeException, 那么必须在函数定义上加上throws后缀. 但反过来就不是必须的.原因上⾯讲过了.七, ⾃定义异常.我们可以⾃定义异常, 只需要编写1个类, 继承1个异常类就ok例⼦:[java]1. package Exception_kng;2.3. class User_Exception1 extends ArithmeticException{4. public User_Exception1(String Exception_name){5. super(Exception_name);6. }7.8. public void printStackTrace(){ //overwrite9. super.printStackTrace();10. System.out.printf("hey man, i am an user_defined excetpion\n");11. }12. }13.14. class Exp6{15. public int f(int a, int b){16. if (0 == b){17. throw new User_Exception1("Shit !!! / by zero!"); //use User_defined exception18. }19.20. return a/b;21. }22. }23.24. public class Expt_6{25. public static void g() {26. Exp6 ex = new Exp6();27. int i = 22;28. try{29. i = ex.f(8,0); //throw excetpion30. }catch(User_Exception1 e){31. e.printStackTrace();32. }33. System.out.printf("i is %d\n", i);34. System.out.printf("g() is done!!\n");35. }36. }上⾯的类User_Exception1 就是1个⾃定义异常, 并重写了printStackTrace()⽅法.⼋,java异常的优缺点.8.1 c语⾔是如何处理程序错误的.我们要理解异常的优缺点, ⾸先看看没有异常的是如何处理错误的.下⾯是个例⼦:[cpp]1. //openfile2. if (fileOpen() > 0){3. //check the length of the file4. if (gotLengthOfTheFile() > 0){5. //check the memory6. if (gotEnoughMemory() > 0){7. //load file to memory8. if (loadFileToMem() > 0){9. readFile();10. }else{11. errorCode = -5;12. }13.14. }else{15. errorCode = -5;16. }17.18. }else{19. errorCode = -5;20. }21.22. }else{23. errorCode = -5;24. }25.26. //handle error27. case errorCode....28.29. //release Source30. releaseSource();可以见到处理错误有这些特点1. ⼤部分精⼒都在错误处理.2. 需要把各种可能出现的错误全部考虑到, 才能保证程序的稳定性.3. 程序可读性差, 错误处理代码混杂在其他代码中.4. 出错返回信息少, ⼀旦出错难以调试.5. ⼀旦出现了未考虑到的错误, 资源释放代码⽆法执⾏.8.2 java异常机制下是如何编写上述代码的.[java]1. try{2. fileOpen();3. gotLengthOfTheFile();4. gotEnoughMemory();5. loadFileToMem();6. readFile();7. }8. catch(fileOpenFail) { handle1()}9. catch(gotLengthOfTheFileFail) { handle2()}10. catch(gotEnoughMemoryFail) { handle3()}11. catch(loadFileToMemFail) { handle4()}12. catch(readFileFail) { handle4()}13. catch(Exception e) { handle5()} //catch unexpected error14. finally{15. releasSource();16. }8.3 java异常机制的优点:由上⾯的代码可以看出部分优点:1. 业务代码和错误处理代码分离.2. 强制程序猿考虑程序的稳定性.3. 有利于代码调试(异常信息)4. 即使任何异常产⽣, 能保证占⽤的释放(finally)8.4 java异常机制的缺点:1. 异常嵌套难免影响代码可读性2. 并不能令程序逻辑更加清晰.3. 异常并不能解决所有问题。
Java中异常分为哪些种类?
Java中异常分为哪些种类?
按照异常需要处理的时机分为编译时异常(也叫受控异常)也叫 CheckedException 和运⾏时异常(也叫⾮受控异常)也叫 UnCheckedException。
Java认为Checked异常都是可以被处理的异常,所以Java程序必须显式处理Checked异常。
如果程序没有处理Checked 异常,该程序在编译时就会发⽣错误⽆法编译。
这体现了Java 的设计哲学:没有完善错误处理的代码根本没有机会被执⾏。
对Checked异常处理⽅法有两种:
第⼀种:当前⽅法知道如何处理该异常,则⽤try…catch块来处理该异常。
第⼆种:当前⽅法不知道如何处理,则在定义该⽅法时声明抛出该异常。
运⾏时异常只有当代码在运⾏时才发⾏的异常,编译的时候不需要try…catch。
Runtime如除数是0和数组下标越界等,其产⽣频繁,处理⿇烦,若显⽰申明或者捕获将会对程序的可读性和运⾏效率影响很⼤。
所以由系统⾃动检测并将它们交给缺省的异常处理程序。
当然如果你有处理要求也可以显⽰捕获它们。
总结了一下JAVA中常见的几种RuntimeException
总结了一下JAVA中常见的几种RuntimeException总结了一下JA V A中常见的几种RuntimeException,大约有如下几种:1.NullPointerException - 空指针引用异常2.ClassCastException - 类型强制转换异常。
3.IllegalArgumentException - 传递非法参数异常。
4.ArithmeticException - 算术运算异常5.ArrayStoreException - 向数组中存放与声明类型不兼容对象异常6.IndexOutOfBoundsException - 下标越界异常7.NegativeArraySizeException - 创建一个大小为负数的数组错误异常8.NumberFormatException - 数字格式异常9.SecurityException - 安全异常10.UnsupportedOperationException - 不支持的操作异常如下:RuntimeException是开发中最容易遇到的,下面列举一下常见的RuntimeException:1、NullPointerException:见的最多了,其实很简单,一般都是在null对象上调用方法了。
String s=null;boolean eq=s.equals(""); // NullPointerException这里你看的非常明白了,为什么一到程序中就晕呢?public int getNumber(String str){if(str.equals("A")) return 1;else if(str.equals("B")) return 2;}这个方法就有可能抛出NullPointerException,我建议你主动抛出异常,因为代码一多,你可能又晕了。
public int getNumber(String str){if(str==null) throw new NullPointerException("参数不能为空");//你是否觉得明白多了if(str.equals("A")) return 1;else if(str.equals("B")) return 2;}2、NumberFormatException:继承IllegalArgumentException,字符串转换为数字时出现。
简述java中的异常处理机制
简述java中的异常处理机制一、概述Java是一种面向对象的编程语言,其异常处理机制是其核心特性之一。
Java的异常处理机制可以让程序员在代码中处理预期和未预期的错误情况,从而提高程序的稳定性和可靠性。
二、异常分类Java中的异常分为两类:受检异常(checked exception)和非受检异常(unchecked exception)。
1. 受检异常受检异常是指在编译时就能够被捕获到的异常,必须要进行处理。
这些异常通常是由于外部环境或用户输入导致的,例如文件不存在、网络连接失败等。
2. 非受检异常非受检异常是指在运行时才能够被捕获到的异常,不需要进行处理。
这些异常通常是由于程序逻辑错误或内存问题导致的,例如空指针引用、数组下标越界等。
三、Exception类及其子类Java中所有的异常都继承自Exception类或RuntimeException类。
其中Exception类包括了所有受检异常,而RuntimeException类包括了所有非受检异常。
1. Exception类Exception类包括了许多子类,如IOException、SQLException等。
这些子类都需要在方法声明中使用throws关键字进行声明或使用try-catch语句进行捕获和处理。
2. RuntimeException类RuntimeException类包括了许多子类,如NullPointerException、ArrayIndexOutOfBoundsException等。
这些子类可以在方法中直接抛出,不需要进行声明或捕获处理。
四、异常处理方式Java中有两种异常处理方式:try-catch语句和throws关键字。
1. try-catch语句try-catch语句用于捕获异常并进行处理。
其基本语法如下:```try {// 可能会抛出异常的代码} catch (ExceptionType e) {// 异常处理代码}```其中,ExceptionType指的是要捕获的异常类型,可以是任何Exception类或其子类。
Java中Exception的种类
Java中Exception的种类转⾃:通常来讲,Java中的异常会被分为三种:1. Error: 这种异常被设计成不被捕获,因为这种异常产⽣于JVM⾃⾝。
2. Runtime Exception: 运⾏时异常往往与环境有关,编译时⽆法检查,并且可能发⽣的情况太⼴泛,所以系统会去处理,程序不需要捕获。
3. 普通异常: 常见的异常⼤多属于此类。
这⾥的Java异常指直接继承ng.Throwable的异常类,他们的结构如下图:ng.Throwableng.Errorng.Exceptionng.RuntimeExceptionng.Throwableng.Throwable是Java中所有可以错误和异常的⽗类。
这⾥设计成⽗类⽽不是接⼝,我想部分原因可能是在Java诞⽣的早期,使⽤类继承结构更为流⾏。
但更重要的原因应该是由于Exception不适于设计为接⼝。
接⼝重视的是实现⽅法,规则的描述,⽽ Exception重视的是⾥⾯含有的信息以及类名等信息。
Throwable的⼦类⼀般含有两个构造函数:空参数的构造函数和带异常信息String参数的构造函数。
如果此类继承⾃其它 Exception类,⼜会多两个构造函数:含Throwable参数的构造函数和含Throwable,描述信息String两个参数的构造函数。
ng.Errorng.Error发⽣在应⽤程序不应该试图捕获的情况。
Java程序不需要去throw或catch此类及其⼦类,因为这种异常不应该由应⽤程序处理,并且通常属于abnormal的情况。
ng.Exceptionng.Exception是指Java程序应该捕获的异常。
其中,ng.RuntimeException是其中⼀个特别的⼦类。
ng.RuntimeExceptionJava程序应该捕获,却可以不去捕获的⼀个异常。
在⼤多数情况下,都不会去捕获他,⼀个重要原因是这种异常可能发⽣的情况太普遍,⼏乎每⾏代码都会有RuntimeException的风险,因此反⽽⽆需去捕获了。
java 容易发生bug的代码
Java作为一种常见的编程语言,在软件开发中被广泛应用。
然而,由于Java语言本身的复杂性和灵活性,以及开发人员的编码习惯等原因,容易导致代码中出现各种各样的bug。
本文将就Java程序中容易发生bug的代码进行探讨,从而帮助开发人员避免在编码过程中犯下一些常见的错误。
一、空指针异常1.1 未对对象进行空值检查在Java中,当一个对象为null时,若再对该对象进行操作就会导致空指针异常。
在编码过程中,需要特别注意对对象进行空值检查,避免出现空指针异常。
1.2 引用对象为空时的操作在编写代码时,需要时刻注意操作的对象是否为空,避免在引用对象为空的情况下进行操作,从而引发空指针异常。
二、数组越界异常2.1 未对数组进行边界检查在使用数组时,需要时刻注意数组的长度和索引的范围,避免出现数组越界异常。
特别是在循环中,需要谨慎判断循环的边界条件,避免出现索引越界的情况。
2.2 循环条件不当在编写循环时,需要特别注意循环条件的合理性,避免出现因为循环条件不当而导致数组越界异常的情况。
三、逻辑错误3.1 未对条件进行全面考虑在编写条件判断语句时,需要考虑全面,确保覆盖所有可能的情况,避免出现逻辑错误。
特别是在多条件判断的情况下,需要仔细思考每种情况的处理方法。
3.2 逻辑判断错误在编写逻辑判断语句时,需要谨慎思考,避免因为逻辑判断错误而导致程序出现逻辑错误的情况。
四、并发问题4.1 线程安全性问题在多线程环境中,需要特别注意共享资源的线程安全性,避免因为多线程操作而引发数据竞争、死锁等并发问题。
4.2 未加锁导致的并发问题在编写多线程程序时,需要考虑对共享资源进行合适的加锁操作,确保在并发情况下共享资源的正确访问。
五、性能问题5.1 未使用合适的数据结构在编写代码时,需要根据实际情况选择合适的数据结构,避免出现性能问题。
选择合适的数据结构能够提高程序的执行效率。
5.2 未考虑算法复杂度在编写算法时,需要考虑算法的时间复杂度和空间复杂度,避免因为未考虑算法复杂度而引发性能问题。
java 容易发生bug的代码
java 容易发生bug的代码在Java中,有几个常见的错误和容易导致bug的代码模式。
下面将介绍其中的一些常见错误,以及如何避免它们。
1.空指针异常(NullPointerException):空指针异常是Java程序中最常见的bug之一。
它发生在尝试访问或操作空对象引用时。
这种错误通常是由于没有对引用进行null检查而导致的。
例如:```String str = null;int length = str.length(); //这里会抛出空指针异常,因为str是空引用```避免空指针异常的方法是始终在使用对象引用之前进行null检查,或者使用可空性注解(如@Nullable和@NonNull)。
此外,还可以在使用对象引用之前,确保对象已正确初始化。
2.数组越界异常(ArrayIndexOutOfBoundsException):数组越界异常是另一种常见的错误,它发生在尝试访问超出数组界限的元素时。
这种错误通常是由于使用不正确的索引或在循环中遍历数组时出错而导致的。
例如:```int[] nums = {1, 2, 3};int num = nums[3]; //这里会抛出数组越界异常,因为数组索引从0开始,而这里使用了索引3```要避免数组越界异常,需要确保在访问数组元素之前检查索引是否在有效范围内。
还可以使用增强的for循环(foreach循环)来遍历数组,以避免手动迭代索引。
3.类型转换异常(ClassCastException):类型转换异常是另一个常见的错误类型,它发生在尝试将一个对象转换为不兼容类型时。
这种错误通常是在进行强制类型转换时出现的。
例如:```Object obj = "Hello";Integer num = (Integer) obj; //这里会抛出类型转换异常,因为String不能直接转换为Integer```要避免类型转换异常,应该在进行强制类型转换之前,使用instanceof运算符检查对象类型。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
3. ng.ArithmeticException
这个异常的解释是"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常,对这种异常,大家就要好好检查一下自己程序中涉及到数学运算的地方,公式是不是有不妥了。
4. ng.ArrayIndexOutOfBoundsException
2. ng.ClassNotFoundException
这个异常是很多原本在JB等开发环境中开发的程序员,把JB下的程序包放在WTk下编译经常出现的问题,异常的解释是"指定的类不存在",这里主要考虑一下类的名称和路径是否正确即可,如果是在JB下做的程序包,一般都是默认加上Package的,所以转到WTK下后要注意把Package的路径加上。
6. ng.IllegalAccessException
这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常。
其他还有很多异常,我就不一一列举了,我要说明的是,一个合格的程序员,需要对程序中常见的问题有相当的了解和相应的解决办法,否则仅仅停留在写程序而不会改程序的话,会极大影响到自己的开发的。关于异常的全部说明,在API里都可以查阅。
1. ng.NullPointerException
这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,这个错误经常出现在创建图片,调用数组这些操作中,比如图片未经初始化,或者图片创建时的路径错误等等。对数组操作中出现空指针,很多情况下是一些刚开始学习编程的朋友常犯的错误,即把数组的初始化和数组元素的初始化混淆起来了。数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)
5. ng.IllegalArgumentException
这个异常的解释是"方法的参数错误",很多J2ME的类库中的方法在一些情况下都会引发这样的错误,比如音量调节方法中的音量参数如果写成负数就会出现这个异常,再比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误。
这个异常相信很多朋友也经常遇到过,异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。