- 浏览: 46355 次
- 性别:
-
文章分类
最新评论
本文重在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运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。
2.2.2 Exception体系 Exception体系包括RuntimeException体系和其他非RuntimeException的体系
2.2.2.1 RuntimeException RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
2.2.2.2 其他(IOException等等)这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
2.3 与C++异常分类的不同
2.3.1 其实,Java中RuntimeException这个类名起的并不恰当,因为任何异常都是运行时出现的。(在编译时出现的错误并不是异常,换句话说,异常就是为了解决程序运行时出现的的错误)。
2.3.2 C++中logic_error与Java中的RuntimeException是等价的,而runtime_error与Java中非RuntimeException类型的异常是等价的。
3 异常的使用方法
3.1 声明方法抛出异常
3.1.1 语法:throws(略)
3.1.2 为什么要声明方法抛出异常?方法是否抛出异常与方法返回值的类型一样重要。假设方法抛出异常确没有声明该方法将抛出异常,那么客户程序员可以调用这个方法而且不用编写处理异常的代码。那么,一旦出现异常,那么这个异常就没有合适的异常控制器来解决。
3.1.3 为什么抛出的异常一定是已检查异常? RuntimeException与Error可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出。而已检查异常是由程序员抛出的,这分为两种情况:客户程序员调用会抛出异常的库函数(库函数的异常由库程序员抛出);客户程序员自己使用throw语句抛出异常。遇到Error,程序员一般是无能为力的;遇到RuntimeException,那么一定是程序存在逻辑错误,要对程序进行修改(相当于调试的一种方法);只有已检查异常才是程序员所关心的,程序应该且仅应该抛出或处理已检查异常。
3.1.4 注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。
3.2 如何抛出异常
3.2.1 语法:throw(略)
3.2.2 抛出什么异常?对于一个异常对象,真正有用的信息时异常的对象类型,而异常对象本身毫无意义。比如一个异常对象的类型是ClassCastException,那么这个类名就是唯一有用的信息。所以,在选择抛出什么异常时,最关键的就是选择异常的类名能够明确说明异常情况的类。
3.2.3 异常对象通常有两种构造函数:一种是无参数的构造函数;另一种是带一个字符串的构造函数,这个字符串将作为这个异常对象除了类型名以外的额外说明。
3.2.4 创建自己的异常:当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。需要注意的是,唯一有用的就是类型名这个信息,所以不要在异常类的设计上花费精力。
3.3 捕获异常如果一个异常没有被处理,那么,对于一个非图形界面的程序而言,该程序会被中止并输出异常信息;对于一个图形界面程序,也会输出异常的信息,但是程序并不中止,而是返回用户界面处理循环中。
3.3.1 语法:try、catch和finally(略)控制器模块必须紧接在try块后面。若掷出一个异常,异常控制机制会搜寻参数与异常类型相符的第一个控制器随后它会进入那个catch 从句,并认为异常已得到控制。一旦catch 从句结束对控制器的搜索也会停止。 3.3.1.1 捕获多个异常(注意语法与捕获的顺序)(略)
3.3.1.2 finally的用法与异常处理流程(略)
3.3.2 异常处理做什么?对于Java来说,由于有了垃圾收集,所以异常处理并不需要回收内存。但是依然有一些资源需要程序员来收集,比如文件、网络连接和图片等资源。
3.3.3 应该声明方法抛出异常还是在方法中捕获异常?原则:捕捉并处理哪些知道如何处理的异常,而传递哪些不知道如何处理的异常
3.3.4 再次抛出异常
3.3.4.1 为什么要再次抛出异常?在本级中,只能处理一部分内容,有些处理需要在更高一级的环境中完成,所以应该再次抛出异常。这样可以使每级的异常处理器处理它能够处理的异常。
3.3.4.2 异常处理流程对应与同一try块的catch块将被忽略,抛出的异常将进入更高的一级。
4 关于异常的其他问题
4.1 过度使用异常首先,使用异常很方便,所以程序员一般不再愿意编写处理错误的代码,而仅仅是简简单单的抛出一个异常。这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。另外,异常机制的效率很差。
4.2 将异常与普通错误区分开对于普通的完全一致的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。只有外部的不能确定和预知的运行时错误才需要使用异常。
4.3 异常对象中包含的信息一般情况下,异常对象唯一有用的信息就是类型信息。但使用异常带字符串的构造函数时,这个字符串还可以作为额外的信息。调用异常对象的getMessage()、toString()或者printStackTrace()方法可以分别得到异常对象的额外信息、类名和调用堆栈的信息。并且后一种包含的信息是前一种的超集。
常用异常:
UnsupportedOperationException不支持的操作
IllegalArgumentException非法参数
IndexOutOfBoundsException索引出界
IllegalStateException非法状态
异常跟普通的警告等有一定的区别。当应用程序发生异常时,会中断正在执行的程序的正常指令流。也就是说,发生异常后面的代码将得不到正确的执行。甚至还会触发数据库的回退操作。
在Java开发平台中,异常包括预定义异常与自定义异常。这两种异常的类型互为补充。作为一个合格的程序开发人员,要善于在应用程序中使用异常。这可以提高应用程序的交互性。同时,也是保证应用程序正常运行的前提。故异常的处理对于开发一个优秀的应用程序来说非常的重要。为此笔者认为程序开发人员应该对Java应用程序的常见异常有一个深入的了解。只有在了解这些常见异常的情况下,才能够做好自定义异常的处理。
一、常见异常的类型与原因。
对于Java应用程序的常见异常,笔者认为程序开发人员要从两个方面去了解。一是要知道有哪些常见的Java应用程序异常,二是需要知道哪些原因可能会造成这个异常。这不仅需要程序管理人员在日常工作中要注意积累,在必要的情况下还需要去从其它渠道收集资料。笔者对此就进行一个分析,希望能够对各位程序开发人员有一定的帮助。
1、 SQLException:操作数据库异常类。
现在的Java应用程序大部分都是依赖于数据库运行的。当Java应用程序与数据库进行沟通时如果产生了错误,就会触发这个类。同时会将数据库的错误信息通过这个类显示给用户。也就是说,这个操作数据库异常类是数据库与用户之间异常信息传递的桥梁。如现在用户往系统中插入数据,而在数据库中规定某个字段必须唯一。当用户插入数据的时候,如果这个字段的值跟现有的纪录重复了,违反了数据库的唯一性约束,此时数据库就会跑出一个异常信息。这个信息一般用户可能看不到,因为其发生在数据库层面的。此时这个操作数据库异常类就会捕捉到数据库的这个异常信息,并将这个异常信息传递到前台。如此的话,前台用户就可以根据这个异常信息来分析发生错误的原因。这就是这个操作数据库异常类的主要用途。在Java应用程序中,所有数据库操作发生异常时,都会触发这一个类。所有此时Java应用程序本身的提示信息往往过于笼统,只是说与数据库交互出现错误,没有多大的参考价值。此时反而是数据库的提示信息更加有使用价值。
2、 ClassCastException:数据类型转换异常。
在Java应用程序中,有时候需要对数据类型进行转换。这个转换包括显示的转换与隐式的转换。不过无论怎么转换,都必须要符合一个前提的条件,即数据类型的兼容性。如果在数据转换的过程中,违反了这个原则,那么就会触发数据类型转换异常。如现在在应用程序中,开发人员需要将一个字符型的日期数据转换为数据库所能够接受的日期型数据,此时只需要在前台应用程序中进行控制,一般不会有问题。但是,如果前台应用程序缺乏相关的控制,如用户在输入日期的时候只输入月、日信息,而没有年份的信息。此时应用程序在进行数据类型转换的时候,就会出现异常。根据笔者的经验,数据类型转换异常在应用程序开发中使一个出现的比较多的异常,也是一个比较低级的异常。因为大部分情况下,都可以在应用程序窗口中对数据类型进行一些强制的控制。即在数据类型进行转换之前,就保证数据类型的兼容性。如此的话,就不容易造成数据类型的转换异常。如在只允许数值类型的字段中,可以设置不允许用户输入数值以外的字符。虽然说有了异常处理机制,可以保证应用程序不会被错误的运行。但是在实际开发中,还是要尽可能多的预见错误发生的原因,尽量避免异常的发生。
3、 NumberFormatException:字符串转换为数字类型时抛出的异常。
在数据类型转换过程中,如果是字符型转换为数字型过程中出现的问题,对于这个异常在Java程序中采用了一个独立的异常,即NumberFormatException.如现在讲字符型的数据“123456”转换为数值型数据时,是允许的。但是如果字符型数据中包含了非数字型的字符,如123#56,此时转换为数值型时就会出现异常。系统就会捕捉到这个异常,并进行处理。
Java应用程序中常见的异常类还有很多。如未找到相应类异常、不允许访问某些类异常、文件已经结束异常、文件未找到异常、字段未找到异常等等。一般系统开发人员都可以根据这个异常名来判断当前异常的类型。虽然不错,但是好记性不如烂笔头。程序开发人员在必要的时候(特别是存在自定义异常的时候),最后手头有一份异常明细表。如此的话,无论是应用程序在调试过程中发现问题,还是运行过程中接到用户的投诉,都可以及时的根据异常名字来找到异常发生的原因。从而可以在最短时间内解决异常,恢复应用程序的正常运行。这个措施笔者用了很多年,非常的有效。
二、异常管理的实用建议。
对于操作数据库异常来说,Java应用程序只提供了一个异常类。故光凭Java应用程序的错误信息,往往不能够帮助应用程序人员排除错误的原因。只能够指名是应用程序错误还是数据库错误导致的这个异常。为了更进一步指明问题的原因,在数据库层面定义异常的时候,最好能够说明具体的原因。如前台应用程序可能会调用数据库的函数或者过程。此时在数据库的函数或者过程中做好能够说明某个异常的具体原因。如根据某个基础表生成另一张表的时候,某个字段不能够为空等等。将这些异常信息说明清楚后,如果真的遇到类似的异常时,操作数据库异常类就会将数据库的异常信息反会给前台用户。从而有利于用户寻找问题的原因,并在最短时间内改正。当然,这需要Java程序员与数据库设计人员进行协调。
其次需要注意的是,异常并不是常态。也就是说,大部分异常可以通过前提的合理预见与预防,来消除。如设计到四则运算,可以在前台应用程序窗口中限制在除数字段内输入0值等手段来消除应用程序运行中可能产生的异常。不过这往往要求应用程序开发人员有比较丰富的工作经验以及由比较严密的思维逻辑。虽然这有一定的难度,但是笔者认为程序开发人员还是应该往这方面努力,而不要老是让用户作为你的试验品,让用户来发现应用程序中的设计Bug.笔者认为,只有一些实在是程序人员无法控制的因素才允许抛出异常。如果应用程序开发人员能够意识到这种错误、但是仍然没有引起重视或者采取有效的措施防止出现这种异常,那么笔者是不允许的。
ArithmeticException(除数为0的异常), BufferOverflowException(缓冲区上溢异常), BufferUnderflowException(缓冲区下溢异常), IndexOutOfBoundsException(出界异常), NullPointerException(空指针异常), EmptyStackException(空栈异常), IllegalArgumentException(不合法的参数异常), NegativeArraySizeException, NoSuchElementException, SecurityException, SystemException, UndeclaredThrowableException
1. java.lang.NullPointerException
异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,即把数组的初始化和数组元素的初始化混淆起来了。数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)
2. java.lang.ClassNotFoundException 异常的解释是"指定的类不存在"。
3. java.lang.ArithmeticException 这个异常的解释是"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常。
4. java.lang.ArrayIndexOutOfBoundsException
异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。
5. java.lang.IllegalArgumentException
这个异常的解释是"方法的参数错误",比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误。
6. java.lang.IllegalAccessException
这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常
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运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。
2.2.2 Exception体系 Exception体系包括RuntimeException体系和其他非RuntimeException的体系
2.2.2.1 RuntimeException RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
2.2.2.2 其他(IOException等等)这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。
2.3 与C++异常分类的不同
2.3.1 其实,Java中RuntimeException这个类名起的并不恰当,因为任何异常都是运行时出现的。(在编译时出现的错误并不是异常,换句话说,异常就是为了解决程序运行时出现的的错误)。
2.3.2 C++中logic_error与Java中的RuntimeException是等价的,而runtime_error与Java中非RuntimeException类型的异常是等价的。
3 异常的使用方法
3.1 声明方法抛出异常
3.1.1 语法:throws(略)
3.1.2 为什么要声明方法抛出异常?方法是否抛出异常与方法返回值的类型一样重要。假设方法抛出异常确没有声明该方法将抛出异常,那么客户程序员可以调用这个方法而且不用编写处理异常的代码。那么,一旦出现异常,那么这个异常就没有合适的异常控制器来解决。
3.1.3 为什么抛出的异常一定是已检查异常? RuntimeException与Error可以在任何代码中产生,它们不需要由程序员显示的抛出,一旦出现错误,那么相应的异常会被自动抛出。而已检查异常是由程序员抛出的,这分为两种情况:客户程序员调用会抛出异常的库函数(库函数的异常由库程序员抛出);客户程序员自己使用throw语句抛出异常。遇到Error,程序员一般是无能为力的;遇到RuntimeException,那么一定是程序存在逻辑错误,要对程序进行修改(相当于调试的一种方法);只有已检查异常才是程序员所关心的,程序应该且仅应该抛出或处理已检查异常。
3.1.4 注意:覆盖父类某方法的子类方法不能抛出比父类方法更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现方法的代码却并不抛出异常,这样做的目的就是为了方便子类方法覆盖父类方法时可以抛出异常。
3.2 如何抛出异常
3.2.1 语法:throw(略)
3.2.2 抛出什么异常?对于一个异常对象,真正有用的信息时异常的对象类型,而异常对象本身毫无意义。比如一个异常对象的类型是ClassCastException,那么这个类名就是唯一有用的信息。所以,在选择抛出什么异常时,最关键的就是选择异常的类名能够明确说明异常情况的类。
3.2.3 异常对象通常有两种构造函数:一种是无参数的构造函数;另一种是带一个字符串的构造函数,这个字符串将作为这个异常对象除了类型名以外的额外说明。
3.2.4 创建自己的异常:当Java内置的异常都不能明确的说明异常情况的时候,需要创建自己的异常。需要注意的是,唯一有用的就是类型名这个信息,所以不要在异常类的设计上花费精力。
3.3 捕获异常如果一个异常没有被处理,那么,对于一个非图形界面的程序而言,该程序会被中止并输出异常信息;对于一个图形界面程序,也会输出异常的信息,但是程序并不中止,而是返回用户界面处理循环中。
3.3.1 语法:try、catch和finally(略)控制器模块必须紧接在try块后面。若掷出一个异常,异常控制机制会搜寻参数与异常类型相符的第一个控制器随后它会进入那个catch 从句,并认为异常已得到控制。一旦catch 从句结束对控制器的搜索也会停止。 3.3.1.1 捕获多个异常(注意语法与捕获的顺序)(略)
3.3.1.2 finally的用法与异常处理流程(略)
3.3.2 异常处理做什么?对于Java来说,由于有了垃圾收集,所以异常处理并不需要回收内存。但是依然有一些资源需要程序员来收集,比如文件、网络连接和图片等资源。
3.3.3 应该声明方法抛出异常还是在方法中捕获异常?原则:捕捉并处理哪些知道如何处理的异常,而传递哪些不知道如何处理的异常
3.3.4 再次抛出异常
3.3.4.1 为什么要再次抛出异常?在本级中,只能处理一部分内容,有些处理需要在更高一级的环境中完成,所以应该再次抛出异常。这样可以使每级的异常处理器处理它能够处理的异常。
3.3.4.2 异常处理流程对应与同一try块的catch块将被忽略,抛出的异常将进入更高的一级。
4 关于异常的其他问题
4.1 过度使用异常首先,使用异常很方便,所以程序员一般不再愿意编写处理错误的代码,而仅仅是简简单单的抛出一个异常。这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。另外,异常机制的效率很差。
4.2 将异常与普通错误区分开对于普通的完全一致的错误,应该编写处理这种错误的代码,增加程序的鲁棒性。只有外部的不能确定和预知的运行时错误才需要使用异常。
4.3 异常对象中包含的信息一般情况下,异常对象唯一有用的信息就是类型信息。但使用异常带字符串的构造函数时,这个字符串还可以作为额外的信息。调用异常对象的getMessage()、toString()或者printStackTrace()方法可以分别得到异常对象的额外信息、类名和调用堆栈的信息。并且后一种包含的信息是前一种的超集。
常用异常:
UnsupportedOperationException不支持的操作
IllegalArgumentException非法参数
IndexOutOfBoundsException索引出界
IllegalStateException非法状态
异常跟普通的警告等有一定的区别。当应用程序发生异常时,会中断正在执行的程序的正常指令流。也就是说,发生异常后面的代码将得不到正确的执行。甚至还会触发数据库的回退操作。
在Java开发平台中,异常包括预定义异常与自定义异常。这两种异常的类型互为补充。作为一个合格的程序开发人员,要善于在应用程序中使用异常。这可以提高应用程序的交互性。同时,也是保证应用程序正常运行的前提。故异常的处理对于开发一个优秀的应用程序来说非常的重要。为此笔者认为程序开发人员应该对Java应用程序的常见异常有一个深入的了解。只有在了解这些常见异常的情况下,才能够做好自定义异常的处理。
一、常见异常的类型与原因。
对于Java应用程序的常见异常,笔者认为程序开发人员要从两个方面去了解。一是要知道有哪些常见的Java应用程序异常,二是需要知道哪些原因可能会造成这个异常。这不仅需要程序管理人员在日常工作中要注意积累,在必要的情况下还需要去从其它渠道收集资料。笔者对此就进行一个分析,希望能够对各位程序开发人员有一定的帮助。
1、 SQLException:操作数据库异常类。
现在的Java应用程序大部分都是依赖于数据库运行的。当Java应用程序与数据库进行沟通时如果产生了错误,就会触发这个类。同时会将数据库的错误信息通过这个类显示给用户。也就是说,这个操作数据库异常类是数据库与用户之间异常信息传递的桥梁。如现在用户往系统中插入数据,而在数据库中规定某个字段必须唯一。当用户插入数据的时候,如果这个字段的值跟现有的纪录重复了,违反了数据库的唯一性约束,此时数据库就会跑出一个异常信息。这个信息一般用户可能看不到,因为其发生在数据库层面的。此时这个操作数据库异常类就会捕捉到数据库的这个异常信息,并将这个异常信息传递到前台。如此的话,前台用户就可以根据这个异常信息来分析发生错误的原因。这就是这个操作数据库异常类的主要用途。在Java应用程序中,所有数据库操作发生异常时,都会触发这一个类。所有此时Java应用程序本身的提示信息往往过于笼统,只是说与数据库交互出现错误,没有多大的参考价值。此时反而是数据库的提示信息更加有使用价值。
2、 ClassCastException:数据类型转换异常。
在Java应用程序中,有时候需要对数据类型进行转换。这个转换包括显示的转换与隐式的转换。不过无论怎么转换,都必须要符合一个前提的条件,即数据类型的兼容性。如果在数据转换的过程中,违反了这个原则,那么就会触发数据类型转换异常。如现在在应用程序中,开发人员需要将一个字符型的日期数据转换为数据库所能够接受的日期型数据,此时只需要在前台应用程序中进行控制,一般不会有问题。但是,如果前台应用程序缺乏相关的控制,如用户在输入日期的时候只输入月、日信息,而没有年份的信息。此时应用程序在进行数据类型转换的时候,就会出现异常。根据笔者的经验,数据类型转换异常在应用程序开发中使一个出现的比较多的异常,也是一个比较低级的异常。因为大部分情况下,都可以在应用程序窗口中对数据类型进行一些强制的控制。即在数据类型进行转换之前,就保证数据类型的兼容性。如此的话,就不容易造成数据类型的转换异常。如在只允许数值类型的字段中,可以设置不允许用户输入数值以外的字符。虽然说有了异常处理机制,可以保证应用程序不会被错误的运行。但是在实际开发中,还是要尽可能多的预见错误发生的原因,尽量避免异常的发生。
3、 NumberFormatException:字符串转换为数字类型时抛出的异常。
在数据类型转换过程中,如果是字符型转换为数字型过程中出现的问题,对于这个异常在Java程序中采用了一个独立的异常,即NumberFormatException.如现在讲字符型的数据“123456”转换为数值型数据时,是允许的。但是如果字符型数据中包含了非数字型的字符,如123#56,此时转换为数值型时就会出现异常。系统就会捕捉到这个异常,并进行处理。
Java应用程序中常见的异常类还有很多。如未找到相应类异常、不允许访问某些类异常、文件已经结束异常、文件未找到异常、字段未找到异常等等。一般系统开发人员都可以根据这个异常名来判断当前异常的类型。虽然不错,但是好记性不如烂笔头。程序开发人员在必要的时候(特别是存在自定义异常的时候),最后手头有一份异常明细表。如此的话,无论是应用程序在调试过程中发现问题,还是运行过程中接到用户的投诉,都可以及时的根据异常名字来找到异常发生的原因。从而可以在最短时间内解决异常,恢复应用程序的正常运行。这个措施笔者用了很多年,非常的有效。
二、异常管理的实用建议。
对于操作数据库异常来说,Java应用程序只提供了一个异常类。故光凭Java应用程序的错误信息,往往不能够帮助应用程序人员排除错误的原因。只能够指名是应用程序错误还是数据库错误导致的这个异常。为了更进一步指明问题的原因,在数据库层面定义异常的时候,最好能够说明具体的原因。如前台应用程序可能会调用数据库的函数或者过程。此时在数据库的函数或者过程中做好能够说明某个异常的具体原因。如根据某个基础表生成另一张表的时候,某个字段不能够为空等等。将这些异常信息说明清楚后,如果真的遇到类似的异常时,操作数据库异常类就会将数据库的异常信息反会给前台用户。从而有利于用户寻找问题的原因,并在最短时间内改正。当然,这需要Java程序员与数据库设计人员进行协调。
其次需要注意的是,异常并不是常态。也就是说,大部分异常可以通过前提的合理预见与预防,来消除。如设计到四则运算,可以在前台应用程序窗口中限制在除数字段内输入0值等手段来消除应用程序运行中可能产生的异常。不过这往往要求应用程序开发人员有比较丰富的工作经验以及由比较严密的思维逻辑。虽然这有一定的难度,但是笔者认为程序开发人员还是应该往这方面努力,而不要老是让用户作为你的试验品,让用户来发现应用程序中的设计Bug.笔者认为,只有一些实在是程序人员无法控制的因素才允许抛出异常。如果应用程序开发人员能够意识到这种错误、但是仍然没有引起重视或者采取有效的措施防止出现这种异常,那么笔者是不允许的。
ArithmeticException(除数为0的异常), BufferOverflowException(缓冲区上溢异常), BufferUnderflowException(缓冲区下溢异常), IndexOutOfBoundsException(出界异常), NullPointerException(空指针异常), EmptyStackException(空栈异常), IllegalArgumentException(不合法的参数异常), NegativeArraySizeException, NoSuchElementException, SecurityException, SystemException, UndeclaredThrowableException
1. java.lang.NullPointerException
异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对象,即把数组的初始化和数组元素的初始化混淆起来了。数组的初始化是对数组分配需要的空间,而初始化后的数组,其中的元素并没有实例化,依然是空的,所以还需要对每个元素都进行初始化(如果要调用的话)
2. java.lang.ClassNotFoundException 异常的解释是"指定的类不存在"。
3. java.lang.ArithmeticException 这个异常的解释是"数学运算异常",比如程序中出现了除以零这样的运算就会出这样的异常。
4. java.lang.ArrayIndexOutOfBoundsException
异常的解释是"数组下标越界",现在程序中大多都有对数组的操作,因此在调用数组的时候一定要认真检查,看自己调用的下标是不是超出了数组的范围,一般来说,显示(即直接用常数当下标)调用不太容易出这样的错,但隐式(即用变量表示下标)调用就经常出错了,还有一种情况,是程序中定义的数组的长度是通过某些特定方法决定的,不是事先声明的,这个时候,最好先查看一下数组的length,以免出现这个异常。
5. java.lang.IllegalArgumentException
这个异常的解释是"方法的参数错误",比如g.setColor(int red,int green,int blue)这个方法中的三个值,如果有超过255的也会出现这个异常,因此一旦发现这个异常,我们要做的,就是赶紧去检查一下方法调用中的参数传递是不是出现了错误。
6. java.lang.IllegalAccessException
这个异常的解释是"没有访问权限",当应用程序要调用一个类,但当前的方法即没有对该类的访问权限便会出现这个异常。对程序中用了Package的情况下要注意这个异常
发表评论
-
【J2SE】Map.Entry 类使用简介
2012-05-10 11:12 532本文转自:http://www.cnblogs.com/guo ... -
【J2SE】Static Nested Class、Inner Class、Anonymous Inner Class
2012-05-05 11:58 0本文转自:http://blog.csdn.net/welco ... -
【J2SE】Anonymous Inner Class (匿名内部类)
2012-05-05 11:56 0本文转自:http://www.iteye ... -
【J2SE】生成者、消费者问题
2012-05-05 11:04 847本文转自:《Java JDK 实例宝典》 解决生产者消费者问 ... -
【J2SE】Java 运行时异常
2012-05-05 10:39 0本文转自:http://amyer.ite ... -
【J2SE】再谈线程:生产者与消费者
2012-05-04 23:36 0本文转自:http://www.blogjava.net/li ... -
【J2SE】Java线程:并发协作-生产者消费者模型
2012-05-04 23:34 0本文转自:http://lavasoft.blog.51cto ... -
【J2SE】线程7种状态的相互转换
2012-05-04 22:48 694本文转自:http://www.blogj ... -
【J2SE】详解java类的生命周期
2012-05-12 21:23 697本文转自:http://www.2cto.com/kf/20 ... -
Java文件操作大全
2012-05-02 13:29 0本文转自:http://www.blog ... -
【基础】Java Annotation详解
2012-05-02 11:50 0本文转自:http://www.blogjava.net/c ... -
【J2SE】Java JDBC数据库连接池总结
2012-05-03 23:21 912本文转自:http://www.blogj ... -
【基础】JAVA中String与StringBuffer的区别
2012-05-01 20:28 0String和StringBuffer的区别,网上资料可以说是 ... -
【基础】Java异常处理及异常机制介绍
2012-05-01 19:54 0当出现程序无法控制的外部环境问题(用户提供的文件不存在,文件内 ... -
【基础】Java中finalize()
2012-05-01 19:39 0垃圾回收器要回收对象的时候,首先要调用这个类的finalize ... -
【基础】finally的一些测试
2012-05-01 16:37 0finally是在执行returen的中间执行。 pac ... -
【J2SE】Java之Path、CLASSPATH的概念解析
2012-05-03 23:17 814本文转自:http://blog.sin ... -
【J2SE】Java 反射机制简述
2012-05-03 23:19 684本文转自:http://zk1878.iteye.com/b ... -
【J2SE】Java中生成对象的4方式
2012-05-01 12:46 0本文转自:http://blog.sina.com.cn/s/ ... -
【J2SE】Anonymous Inner Class 匿名内部类
2012-04-27 19:05 781本文转自: public class T ...
相关推荐
本文将围绕Java的基础知识、进阶概念以及一些常见面试题进行探讨,帮助读者深入理解Java J2SE(Java标准版)和J2EE(Java企业版)的学习要点。 1. 面向对象思想:面向对象编程(OOP)是Java的核心,它强调通过对象...
#### 小结 无论是J2EE还是J2SE项目,路径获取都是开发过程中必不可少的一部分。合理选择路径获取方法,不仅能够提高程序的可移植性和可维护性,还能够避免因路径问题导致的各种异常情况。以上介绍的方法涵盖了大...
【Java课程设计】本次课程设计的目标是开发一个基于图形用户界面(GUI)的计算器应用程序,能够执行基本的算术运算,...最终的设计体会和小结,可以帮助学生反思和总结整个开发过程,为今后的学习和工作提供宝贵的经验。
4-2-4 小结 4-3 移动设备上的开发套件-MIDP 4-3-1 Java与无线通信 4-3-2 MIDP的由来 4-3-3 MIDP开发环境 4-3-4 MIDP开发实例 4-3-5 MIDP的移植 4-3-6 小结 4-4 Symbian Java Phone 4-4-1 Java Phone架构 4...
软件工程第三章实验报告.docx
第三章-第八节通信礼仪.ppt
智能家居股份合作协议.docx
内容概要:本文详细介绍了基于西门子S7-1200 PLC的双轴定位控制系统在电池焊接项目中的应用。主要内容涵盖双轴定位算法的设计与实现,包括使用SCL语言编写的运动控制函数块,以及梯形图用于处理IO互锁和焊接时序控制。文中还讨论了威纶通触摸屏的界面设计,如动态元素映射、宏指令的应用,以及电气图纸的安全回路设计。此外,文章分享了多个调试技巧和注意事项,如加速度参数设置、伺服驱动器订货号核对、BOM清单管理等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是熟悉PLC编程和触摸屏界面设计的专业人士。 使用场景及目标:适用于需要深入了解PLC编程、运动控制算法、触摸屏界面设计及电气图纸绘制的工程项目。目标是提高双轴定位控制系统的精度和稳定性,确保电池焊接的质量和安全性。 其他说明:文中提供了完整的工程文件包下载链接,并强调了在实际应用中需要注意的具体事项,如硬件配置检查、参数调整等。
内容概要:本文详细介绍了如何利用Simulink和Carsim进行联合仿真,实现基于PID(比例-积分-微分)和MPC(模型预测控制)的自适应巡航控制系统。首先阐述了Carsim参数设置的关键步骤,特别是cpar文件的配置,包括车辆基本参数、悬架系统参数和转向系统参数的设定。接着展示了Matlab S函数的编写方法,分别针对PID控制和MPC控制提供了详细的代码示例。随后讨论了Simulink中车辆动力学模型的搭建,强调了模块间的正确连接和参数设置的重要性。最后探讨了远程指导的方式,帮助解决仿真过程中可能出现的问题。 适合人群:从事汽车自动驾驶领域的研究人员和技术人员,尤其是对Simulink和Carsim有一定了解并希望深入学习联合仿真的从业者。 使用场景及目标:适用于需要验证和优化自适应巡航控制、定速巡航及紧急避撞等功能的研究和开发项目。目标是提高车辆行驶的安全性和舒适性,确保控制算法的有效性和可靠性。 其他说明:文中不仅提供了理论知识,还有大量实用的代码示例和避坑指南,有助于读者快速上手并应用于实际工作中。此外,还提到了远程调试技巧,进一步提升了仿真的成功率。
内容概要:本文深入探讨了利用MATLAB/Simulink搭建变压器励磁涌流仿真模型的方法和技术。首先介绍了空载合闸励磁涌流仿真模型的搭建步骤,包括选择和配置电源模块、变压器模块以及设置相关参数。文中详细讲解了如何通过代码生成交流电压信号和设置变压器的变比,同时强调了铁芯饱和特性和合闸角控制的重要性。此外,还讨论了电源简化模型的应用及其优势,如使用受控电压源替代复杂电源模块。为了更好地理解和分析仿真结果,文章提供了绘制励磁涌流曲线的具体方法,并展示了如何提取和分析涌流特征量,如谐波含量和谐波畸变率。最后,文章指出通过调整电源和变压器参数,可以实现针对不同应用场景的定制化仿真,从而为实际工程应用提供理论支持和技术指导。 适合人群:从事电力系统研究、变压器设计及相关领域的科研人员、工程师和技术爱好者。 使用场景及目标:适用于希望深入了解变压器励磁涌流特性的研究人员,旨在帮助他们掌握MATLAB/Simulink仿真工具的使用技巧,提高对励磁涌流现象的理解和预测能力,进而优化继电保护系统的设计。 其他说明:文中不仅提供了详细的建模步骤和代码示例,还分享了一些实用的经验和技巧,如考虑磁滞效应对涌流的影响、避免理想断路器带来的误差等。这些内容有助于读者在实践中获得更加准确可靠的仿真结果。
内容概要:本文详细介绍了利用三菱FX3U PLC与Factory IO通讯仿真进行PID液位调节的方法,旨在降低学习PID控制的成本和难度。文中首先指出了传统硬件学习PID控制面临的高昂成本和复杂接线问题,随后介绍了仿真程序的优势,包括PID配置参数、调节参数、自整定和手动整定的学习方法。接着阐述了所需的设备和软件环境,以及具体的代码示例和寄存器配置。最后,通过实例展示了如何通过仿真环境进行PID参数调整和测试,验证了该方案的有效性和实用性。 适合人群:初学者和有一定PLC基础的技术人员,特别是那些希望通过低成本方式学习PID控制的人群。 使用场景及目标:适用于希望在不购买昂贵硬件的情况下,快速掌握PID控制原理和技术的应用场景。目标是通过仿真环境,熟悉PID参数配置和调整,最终能够应用于实际工业控制系统中。 其他说明:本文不仅提供了理论指导,还给出了详细的实践步骤和代码示例,使读者能够在实践中更好地理解和掌握PID控制技术。同时,强调了仿真环境与实际项目的相似性,便于知识迁移。
智慧城市树木二维码智能管理系统概述.docx
内容概要:本文详细介绍了基于.NET框架和Oracle数据库构建的大型MES(制造执行系统)生产制造管理系统的源码结构及其技术特点。该系统采用了BS架构,适用于Web端和WPF客户端,涵盖了从数据库设计、业务逻辑处理到前端展示等多个方面。文中不仅提供了具体的代码示例,还深入剖析了系统的技术难点,如Oracle数据库的高效连接方式、多线程处理、实时数据推送以及高级特性(如分区表、压缩技术和批量操作)的应用。此外,作者还分享了一些关于系统部署和维护的经验。 适合人群:主要面向拥有五年以上.NET开发经验的专业人士,特别是那些对Oracle数据库有一定了解并且参与过大中型项目开发的技术人员。 使用场景及目标:①帮助开发者深入了解MES系统的工作原理和技术实现;②为现有的MES系统提供优化思路;③作为学习资料,用于掌握.NET框架与Oracle数据库的最佳实践。 其他说明:尽管缺少完整的安装说明和数据库备份文件,但凭借丰富的代码片段和技术细节,这套源码仍然是一个宝贵的学习资源。同时,文中提到的一些技术点也可以应用于其他类型的工业控制系统或企业管理信息系统。
lesson6_点阵.zip
OpenNMS 依赖组件 jicmp 的完整解析与安装指南 一、jicmp 的核心作用 ICMP 协议支持 jicmp(Java Interface for ICMP)是 OpenNMS 实现网络设备可达性检测(如 Ping)的关键组件,通过原生代码高效处理 ICMP 报文,替代纯 Java 实现的性能瓶颈17。 依赖版本要求:OpenNMS 33.1.5 需 jicmp >= 3.0.0,以支持 IPv6 及多线程优化7。 与 jicmp6 的协同 jicmp6 是 jicmp 的扩展组件,专用于 IPv6 网络环境检测,二者共同构成 OpenNMS 网络监控的底层通信基础78。 二、jicmp 安装问题的根源 仓库版本不匹配 OpenNMS 官方旧版仓库(如 opennms-repo-stable-rhel6)仅提供 jicmp-2.0.5 及更早版本,无法满足新版 OpenNMS 的依赖需求78。 典型错误:Available: jicmp-2.0.5-1.el6.i386,但 Requires: jicmp >= 3.0.07。 手动编译未注册到包管理器 手动编译的 jicmp 未生成 RPM 包,导致 yum 无法识别已安装的依赖,仍尝试从仓库拉取旧版本57。 三、解决方案:正确安装 jicmp 3.0 通过源码编译生成 RPM 包 bash Copy Code # 安装编译工具链 yum install -y rpm-build checkinstall gcc-c++ autoconf automake libtool # 编译并生成 jicmp-3.0.0 RPM wget https://sourceforge.net/projects/opennms/files/JICMP/stable-3.x/j
机械CAD零件图.ppt
内容概要:本文详细介绍了制冷站智能群控管理系统的构成及其核心技术实现。首先阐述了系统的四大组成部分:环境感知模块、数据处理模块、决策控制模块以及设备控制模块。接着通过具体的Python代码示例展示了如何利用MQTT协议进行设备间的通信,实现了温度控制等功能。此外,文中还探讨了数据处理中的噪声过滤方法、设备控制中的状态锁定机制、以及采用强化学习进行能效优化的具体案例。最后展望了未来的发展方向,如引入能量管理和AI集成等。 适合人群:从事制冷站自动化控制领域的工程师和技术人员,尤其是对智能群控管理系统感兴趣的从业者。 使用场景及目标:适用于希望提升制冷站自动化水平的企业和个人。目标在于提高系统的稳定性和效率,减少人为干预,实现节能减排。 其他说明:文章不仅提供了理论性的介绍,还有大量的实战经验和代码片段分享,有助于读者更好地理解和应用相关技术。
内容概要:本文详细介绍了将卷积神经网络(CNN)从软件到硬件的全过程部署,特别是在FPGA上的实现方法。首先,作者使用TensorFlow 2构建了一个简单的CNN模型,并通过Python代码实现了模型的训练和权值导出。接着,作者用Verilog手写了CNN加速器的硬件代码,展示了如何通过参数化配置优化加速效果。硬件部分采用了滑动窗口和流水线结构,确保高效执行卷积操作。此外,文中还讨论了硬件调试过程中遇到的问题及其解决方案,如ReLU激活函数的零值处理和权值存储顺序的对齐问题。最后,作者强调了参数化设计的重要性,使得硬件可以在速度和面积之间灵活调整。 适合人群:对深度学习和FPGA感兴趣的开发者,尤其是有一定编程基础和技术背景的研究人员。 使用场景及目标:适用于希望深入了解CNN算法硬件实现的人群,目标是掌握从软件到硬件的完整部署流程,以及如何通过FPGA加速深度学习任务。 其他说明:文中提供了详细的代码片段和调试经验,有助于读者更好地理解和实践。同时,项目代码可在GitHub上获取,方便进一步研究和改进。
内容概要:本文详细介绍了无人驾驶车辆高速MPC(模型预测控制)控制系统的复现过程,主要涉及MATLAB和CarSim软件工具的应用。作者通过调整caraim文件、构建Simulink控制逻辑以及优化MPC算法,将原有的直线跟车场景成功转换为双移线场景。文中不仅展示了具体的技术实现步骤,如路径点设置、权重矩阵调整、采样时间对齐等,还分享了调试过程中遇到的问题及其解决方案,如参数不匹配、模型不收敛等。最终实现了车辆在虚拟环境中按预定双移线轨迹行驶的目标。 适合人群:从事无人驾驶车辆研究和技术开发的专业人士,尤其是对MPC控制算法感兴趣的工程师。 使用场景及目标:适用于需要深入了解无人驾驶车辆控制系统的设计与实现的研究人员和技术开发者。目标是帮助读者掌握如何利用MATLAB和CarSim进行无人驾驶车辆的模拟实验,特别是在高速场景下的双移线控制。 其他说明:文章强调了MPC在高速场景下的挑战性和调参技巧,提供了宝贵的实践经验。同时提醒读者注意环境配置、控制器核心代码解析以及联合仿真可能出现的问题。
监控场景下基于CLIP的细粒度目标检测方法.pdf