java中什么是异常,为什么要进行异常处理,java常遇到的异常
如何解决写爬虫IP受阻的问题?立即使用。
一、异常的定义(推荐:java视频教程)
在《java编程思想》中,异常被定义为阻止当前方法或作用域继续执行的问题。尽管java中有异常处理机制,但应该清楚的是,永远不应该以‘正常’的态度对待异常。绝对来说,异常是某种意义上的错误,也就是问题,可能导致程序失败。java之所以提出异常处理机制,是为了告诉开发者你的程序出现了异常情况。请注意。
我记得我在学习java的时候,总是对异常感到困惑。不知道这个异常是什么意思,为什么会有这个机制?但是随着知识的积累,我渐渐觉得有点不正常了。举例说明异常的使用。
公共类计算器{
public int devide(int num1,int num2) {
//确定除数是否为0
if(num2==0) {
抛出New IllegalArgumentException(“除数不能为零”);
}
返回num 1/num 2;
}
}看看这节课中关于除运算的方法。如果是新手,可能会直接返回计算结果,不考虑任何参数是否正确合法(当然可以原谅,大家都是这样过来的)。但是要尽可能的考虑周全,把可能导致程序失败的‘苗头’扼杀在萌芽状态,所以要检查参数的合法性。
参数检查抛出的非法参数异常是该方法的异常情况。一般情况下,我们会正确使用计算器,但不排除不小心把除数赋为0。如果你之前没有考虑过这种情况,恰好用户数学基础不好,那你就完了。但是如果你以前考虑过这种情况,很明显错误在你的控制之下。
二。异常读写动作
今天和别人聊天的时候看到一个笑话:世界上最真实的依赖就是你在尝试,我在捕捉。不管你脾气如何,我都会默默承受,默默处理。大多数新手对java异常的感受是:试试.捕捉.是的,这是用的最多的,也是最实用的。我的感觉是java异常来自于“尝试”.捕捉.
首先,熟悉一下java的异常系统:
Throwable类是Java语言中所有错误或异常的超类(这是所有可以扔掉的东西)。它有两个子类:错误和异常。
错误:用于指示一个合理的应用程序不应该试图捕捉的严重问题。这种情况是你处理不了的大问题,就顺其自然吧,你不用担心。比如VirtualMachineError:当Java虚拟机崩溃或者用完了继续运行所需的资源时,就会抛出这个错误。那么,即使这种异常存在,我们应该在什么时候以及如何处理它呢?交给JVM吧,没有比它更专业的了。
异常:它表示一个合理的应用程序想要捕捉的条件。异常分为两类:一类是CheckedException,一类是UncheckedException。
这两种异常的区别在于,CheckedException需要由try捕获.捕捉.而不需要捕获UncheckedException。通常UncheckedException也称为RuntimeException。
我们常见的RuntimeExcepiton有IllegalArgumentException、IllegalStateException、NullPointerException、IndexOutOfBoundsException等等。有太多的检查异常,以及我们尝试的异常.捕捉.编写程序过程中的catch都是checkedexceptions。io包中的IOException及其子类,这些是CheckedException。
三。异常使用
这部分的异常使用主要是为了演示代码,这些都是我们在编写代码的过程中会遇到的(当然只是一小部分)。抛砖引玉吧!
1.这个例子主要是通过比较两种方法来演示代码在异常后的执行过程。
公共静态void testException1() {
int[] ints=new int[] { 1,2,3,4 };
System.out.println(异常发生前);
尝试{
system . out . println(ints[4]);
System.out.println(我还有幸执行它吗);//异常发生后,下面的代码无法执行。
} catch(IndexOutOfBoundsException e){
System.out.println(数组越界错误);
}
System.out.println(异常发生后);
}
/*输出:
在异常发生之前
数组越界错误
四
异常发生后
*/public static void testexception 2(){
int[] ints=new int[] { 1,2,3,4 };
System.out.println(异常发生前);
system . out . println(ints[4]);
System.out.println(我还有幸执行它吗);//异常发生后,他后面的代码无法执行。
}首先指出例子中的不足。IndexOutofBoundsException是一个未检查的异常,所以没有必要尝试.捕捉.display capture,但我的目的是用不同的方式对待同一个异常,看看会有怎样的不同和结果(这里只能将就一下)。当异常发生时,第一个方法只是跳出try块,但是它后面的代码仍然会执行。
但是第二个不一样。它直接跳出方法,更强硬。从第一种方法,我们可以看到尝试.捕捉.是一种“交易性”保证。其目的是保证程序在异常情况下运行,同时会告知程序员程序中错误的细节(这样的细节有时取决于程序员的设计)。
2.再次抛出异常
公共类重新抛出{
公共静态void readFile(字符串文件)引发FileNotFoundException {
尝试{
BufferedInputStream in=new BufferedInputStream(new file inputstream(file));
} catch(file not found exception e){
e . printstacktrace();
System.err.println(我不知道如何处理异常或者根本不想处理,但是不处理是不合适的。这是重新抛出异常并将其交给上一级’);
//重新引发异常
扔e;
}
}
公共静态void printFile(字符串文件){
尝试{
readFile(文件);
} catch(file not found exception e){
e . printstacktrace();
}
}
公共静态void main(String[] args) {
print file( D:/file );
}
}例外的意图是好的。让我们尝试修复程序,但实际上,我们修复它的机会非常小。我们经常用它来记录错误的信息。如果您厌倦了不断处理异常,那么重新抛出异常可能是一种很好的解脱。把这个异常按原样丢给上一级,丢给调用这个方法的人,让他过不去。这样一来,java异常(当然是指检测到的异常)就给我们增加了很多麻烦,尽管它的出发点是好的。
3.异常链的使用和异常损失
定义三个异常类:异常A、异常B和异常c。
公共类异常扩展异常{
公共异常(字符串)
super();
}
}
公共类异常扩展异常{
公共异常b(字符串str) {
超级(str);
}
}
公共类异常扩展异常{
公共异常c(字符串str) {
超级(str);
}
}非正常损失:
从未捕获公共类{
静态void f()引发异常{
抛出新的exception b(“exception b”);
}
静态void g()抛出异常{
尝试{
f();
} catch (ExceptionB e) {
exception c=new exception c( exception a );
扔c;
}
}
公共静态void main(String[] args) {
尝试{
g();
} catch(异常情况){
e . printstacktrace();
}
}
}
/*
例外。例外c
例外。never catched . g(never catched . Java:12)
例外。never catched . main(never catched . Java:19)
*/为什么只打印了ExceptionC而没有打印ExceptionB?这个我们自己分析吧!
以上情况相当于漏了一个异常,在我们排查的过程中非常不利。遇到以上情况我们该怎么办?这就是异常链的用武之地:保存异常信息,抛出另一个异常而不丢失原始异常。
从未捕获公共类{
静态void f()引发异常{
抛出新的exception b(“exception b”);
}
静态void g()抛出异常{
尝试{
f();
} catch (ExceptionB e) {
exception c=new exception c( exception a );
//异常连接
c . init cause(e);
扔c;
}
}
公共静态void main(String[] args) {
尝试{
g();
} catch(异常情况){
e . printstacktrace();
}
}
}
/*
例外。例外c
例外。never catched . g(never catched . Java:12)
例外。never catched . main(never catched . Java:21)
原因:异常。例外b
例外。never catched . f(never catched . Java:5)
例外。never catched . g(never catched . Java:10)
.1更
*/这个异常链的特征是所有异常共有的,因为这个initCause()方法是从Throwable继承的。
4.清洁工作
清理对我们来说是必不可少的,因为如果一些消耗资源的操作,如木卫一和木卫二,JDBC。如果我们在使用后没有及时正确的关闭,后果会很严重,也就是内存泄露。异常的出现要求我们设计一种机制,在任何情况下都能及时正确地清理资源。这终于。
公共void readFile(字符串文件){
BufferedReader reader=null
尝试{
reader=new buffered reader(new InputStreamReader(
new file inputstream(file)));
//做一些其他的工作
} catch(file not found exception e){
e . printstacktrace();
}最后{
尝试{
reader . close();
} catch (IOException e) {
e . printstacktrace();
}
}
}例子很简单。这是一个读取文件的例子。这种例子在JDBC行动中也很常见。所以我觉得及时正确的清理资源是一个程序员的基本素质之一。)
尝试.最后,结构也是确保资源正确关闭的一种手段。如果你不知道代码执行过程中会发生什么异常情况,导致资源没有被清理,那么你可以用try把这个‘可疑’的代码包装起来,然后在最后清理资源。举个例子:
公共void readFile() {
BufferedReader reader=null
尝试{
reader=new buffered reader(new InputStreamReader(
new file inputstream( file ));
//做一些其他的工作
//关闭阅读器
reader . close();
} catch(file not found exception e){
e . printstacktrace();
} catch (IOException e) {
e . printstacktrace();
}
}我们来关注一下这个方法和上一个的区别。下一个人可能会更好地习惯它,并尽早关闭阅读器。但往往事与愿违,因为在reader.close()之前,异常随时都有可能发生,这样的代码结构无法阻止任何异常。因为程序会在异常发生的地方跳出来,下面的代码就无法执行了(这个要用上面的例子来证明)。然后我们可以使用try.最后要转型:
公共void readFile() {
BufferedReader reader=null
尝试{
尝试{
reader=new buffered reader(new InputStreamReader(
new file inputstream( file ));
//做一些其他的工作
//关闭阅读器
}最后{
reader . close();
}
} catch(file not found exception e){
e . printstacktrace();
} catch (IOException e) {
e . printstacktrace();
}
}尽早关闭资源是一个好的行为,因为时间越长,你就越有可能忘记关闭它们。就这样,试试.finally保证万无一失(别担心,java就是这么规范)。
另一种情况,如果我想在构造函数中打开一个文件或者创建一个JDBC连接,因为我们必须在其他方法中使用这个资源,所以我们不能在构造函数的早期关闭这个资源。那我们就无能为力了吗?答案是否定的。看看下面的例子:
公共类资源构造器{
BufferedReader reader=null
公共资源构建器(){
尝试{
reader=new buffered reader(new InputStreamReader(new file inputstream()));
} catch(file not found exception e){
e . printstacktrace();
}
}
公共void readFile() {
尝试{
while(reader.readLine()!=null) {
//做一些工作
}
} catch (IOException e) {
e . printstacktrace();
}
}
public void dispose() {
尝试{
reader . close();
} catch (IOException e) {
e . printstacktrace();
}
}
}这部分说的多一点,但是异常真的是看起来好用但是用起来很难的东西。java还有很多东西可以深挖。
四。异常误用
不寻常的误用是很常见的,前一部分已经列举了几种。请仔细看看。再说另外两个。
1.用一个异常来捕获所有的异常,这很有‘一人守之,万人不得’的气魄。但这也是最愚蠢的行为。
公共void readFile(字符串文件){
BufferedReader reader=null
连接连接=空;
尝试{
reader=new buffered reader(new InputStreamReader(
new file inputstream(file)));
//做一些其他的工作
conn=driver manager . getconnection( );
//.
} catch(异常e) {
e . printstacktrace();
}最后{
尝试{
reader . close();
conn . close();
} catch(异常e) {
e . printstacktrace();
}
}
}从异常的角度来说,这么严格的程序真的是万无一失,所有的异常都能被捕捉到。但是站在程序员的角度,如果这个程序出了问题,我们怎么知道是什么原因造成的呢?木卫一或JDBC.所以,这篇文字值得作为反例。不要以为这种做法很幼稚,只有傻子才会这么做。我在公司实习的时候确实看到过类似的情况:只是大家不用Exception,而是用Throwable。
2.这里就不举例了。以上程序都是反例。它是异常程序处理意外情况的机制。当节目中发生事故时,我们需要获取尽可能多的信息,包括事故发生的地点、描述、原因等等。
这些都是我们解决问题的线索。但上面的例子只是简单的printStackTrace()。如果我们编写自己的代码,我们应该尽可能多地描述这个异常。比如为什么会出现这种异常,什么情况下会出现这种异常。如果传入方法的参数不正确,告诉什么样的参数是合法的,或者举个例子。
3.把try块写短,不要把所有东西都扔在这里。我们尽量分析哪几行程序可能有异常,只试可能有异常的代码。试着写一个尝试.捕捉每个异常以避免异常丢失。
更多java知识,请关注java基础课程专栏。以上是你必须知道的java中异常的细节。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。