异常处理方法
对于非运行时异常(checked exception),必须要对其进行处理,否则无法通过编译。
处理方式有两种:
1.使用try..catch..finally进行捕获;
2.在产生异常的方法声明后面写上throws 某一个Exception类型,如throws Exception,将异常抛出到外面一层去。
对非运行时异常的处理详见代码例子:
处理方式1:将异常捕获
public class ExceptionTest2
{
public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
{
System.out.println("Hello World"); // 抛出异常
throw new Exception();
} public static void main(String[] args)
{
ExceptionTest2 test = new ExceptionTest2(); try
{
test.method();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
System.out.println("Welcome");
} } }
处理方式2:将异常继续向外抛出
public class ExceptionTest2
{
public void method() throws Exception // 将异常抛出,由调用这个方法的方法去处理这个异常,如果main方法也将异常抛出,则交给Java虚拟机来处理
{
System.out.println("Hello World"); // 抛出异常
throw new Exception();
} public static void main(String[] args) throws Exception // main方法选择将异常继续抛出
{
ExceptionTest2 test = new ExceptionTest2(); test.method(); // main方法需要对异常进行处理 // 执行结果:
// Hello World
// Exception in thread "main" java.lang.Exception
// at com.learnjava.exception.ExceptionTest2.method(ExceptionTest2.java:10)
// at com.learnjava.exception.ExceptionTest2.main(ExceptionTest2.java:17)
} }
对于运行时异常(runtime exception),可以对其进行处理,也可以不处理。推荐不对运行时异常进行处理。
自定义异常
所谓自定义异常,通常就是定义一个类,去继承Exception类或者它的子类。因为异常必须直接或者间接地继承自Exception类。
通常情况下,会直接继承自Exception类,一般不会继承某个运行时的异常类。
自定义异常可以用于处理用户登录错误,用户输入错误提示等。
自定义异常的例子:
自定义一个异常类型:
public class MyException extends Exception
{
public MyException()
{
super();
}
public MyException(String message)
{
super(message);
}
}
一种异常处理方式
public class ExceptionTest4
{ public void method(String str) throws MyException
{
if(null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else
{
System.out.println(str);
}
} public static void main(String[] args) throws MyException //异常处理方式1,不断向外抛出
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null);
}
}
另一种异常处理方式:
public class ExceptionTest4
{ public void method(String str) throws MyException
{
if (null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else
{
System.out.println(str);
}
} public static void main(String[] args)
{
//异常处理方式2,采用try...catch语句
try
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null); }
catch (MyException e)
{
e.printStackTrace();
}
finally
{
System.out.println("程序处理完毕");
} }
}
前面说过,可以有多个catch块,去捕获不同的异常,真正执行的时候最多只进入一个catch块。
下面这个例子,定义了两种自定义的异常类型:
public class MyException extends Exception
{ public MyException()
{
super();
} public MyException(String message)
{
super(message);
}
} public class MyException2 extends Exception
{
public MyException2()
{
super();
}
public MyException2(String message)
{
super(message);
} } public class ExceptionTest4
{ public void method(String str) throws MyException, MyException2
{
if (null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else if ("hello".equals(str))
{
throw new MyException2("传入的字符串不能为hello");
}
else
{
System.out.println(str);
}
} public static void main(String[] args)
{
// 异常处理方式2,采用try...catch语句
try
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null); }
catch (MyException e)
{
System.out.println("进入到MyException catch块");
e.printStackTrace();
}
catch (MyException2 e)
{
System.out.println("进入到MyException2 catch块");
e.printStackTrace();
}
finally
{
System.out.println("程序处理完毕");
} }
}
我们可以使用多个catch块来捕获异常,这时需要将父类型的catch块放到子类型的catch块之后,这样才能保证后续的catch块可能被执行,否则子类型的catch块将永远无法到达,Java编译器会报错。
如果异常类型是独立的,那么它们的前后顺序没有要求。
如对上面的代码进行改动后,如下列出:
public class ExceptionTest4
{ public void method(String str) throws Exception // 也可以声明Exception,只要声明的可以涵盖所有抛出的异常即可
{
if (null == str)
{
throw new MyException("传入的字符串参数不能为null!");
}
else if ("hello".equals(str))
{
throw new MyException2("传入的字符串不能为hello");
}
else
{
System.out.println(str);
}
} public static void main(String[] args)
{
// 异常处理方式2,采用try...catch语句
try
{
ExceptionTest4 test = new ExceptionTest4();
test.method(null); }
catch (MyException e)
{
System.out.println("进入到MyException catch块");
e.printStackTrace();
}
catch (MyException2 e)
{
System.out.println("进入到MyException2 catch块");
e.printStackTrace();
}
catch (Exception e)
{
//虽然需要加上,但是这块代码不会被执行,只是为了编译成功
System.out.println("进入到MyException catch块");
e.printStackTrace();
//如果去掉前面两个catch块或其中之一,则发生该异常时就会进入此catch块
//catch块的匹配是按照从上到下的顺序,所以这个块如果放在最前面就会捕获所有的异常,后面的块永远不会执行,这时候会提示编译错误
}
finally
{
System.out.println("程序处理完毕");
} }
}
面试常考题型
try块中的退出语句
虽然实际开发中不会遇到这样的情况,但是笔试面试时有关异常经常会问到如下情况:
public class ExceptionTest5
{ public void method()
{
try
{
System.out.println("进入到try块"); //return;
//会先执行finally块再返回 //虚拟机退出
//System.exit(0);
//不会执行finally块中的语句,直接退出
}
catch (Exception e)
{
System.out.println("异常发生了!"); }
finally
{
System.out.println("进入到finally块"); } System.out.println("后续代码"); } public static void main(String[] args)
{
ExceptionTest5 test = new ExceptionTest5();
test.method();
}
}
在加上return语句前,程序输出:
进入到try块
进入到finally块
后续代码
如果在try块中加入return语句:
程序执行输出:
进入到try块
进入到finally块
说明try块中有return语句时,仍然会首先执行finally块中的语句,然后方法再返回。
如果try块中存在System.exit(0);语句,那么就不会执行finally块中的代码,因为System.exit(0)会终止当前运行的Java虚拟机,程序会在虚拟机终止前结束执行。
本文转载自http://www.cnblogs.com/mengdd/archive/2013/02/03/2890923.html,感谢原作者
java异常知识点汇总的更多相关文章
-
Java面试知识点汇总
Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总 版权声明 ...
-
java异常知识点整理
异常处理机制:捕获异常(try-catch-finally)和声明抛弃异常(throw); 所有的异常类都直接或者间接地继承于Throwable类: java异常分为可查异常和不可查异常两种.可查异常 ...
-
java io知识点汇总FIle类
1.路径分隔符问题: 因为java有跨平台行,而在windows和linux中的目录分隔符是不同的.windows是"\" 而linux是"/" 所以必须想办 ...
-
java小知识点汇总
1.ConcurrentHashMap使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安 ...
-
Java 面试知识点汇总
OOP:(Object Oriented Programming )面向对象编程 重用性.灵活性和扩展性 高内聚.低耦合 面向过程编程与面向对象编程的区别:举例,自己做饭吃与去饭馆吃,去饭馆只需要知道 ...
-
JAVA学习知识点汇总
异常处理 1.在异常处理中,如果子类覆盖了父类的一个方法,子类方法中声明的已检查异常不能比父类方法声明的异常更通用,即子类方法可以抛出更特定的异常(不超过父类方法声明的异常范围,即由父类方法声明异常派 ...
-
Java WebService 知识点汇总
java webservice 获取传入IP axis.jar servlet.jar MessageContext mMsgContext = MessageContext.getCurren ...
-
java多线程知识点汇总(一)多线程基础
1.什么叫多线程程序? 答:一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序. java编写的程序都是多线程的,因为最少有俩线程,main主线程和gc线程. ...
-
Java 常用知识点汇总(数据类型之间转换、字符串的相关操作-截取、转换大小写等)
1.Java四类八种数据类型 byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围- ...
随机推荐
-
bzoj4337: BJOI2015 树的同构
hash大法好 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...
-
【leetcode】Next Permutation(middle)
Implement next permutation, which rearranges numbers into the lexicographically next greater permuta ...
-
C#使用ICSharpCode.SharpZipLib.dll压缩文件夹和文件
大家可以到http://www.icsharpcode.net/opensource/sharpziplib/ 下载SharpZiplib的最新版本,本文使用的版本为0.86.0.518,支持Zip, ...
-
为什么X86汇编中的mov指令不支持内存到内存的寻址?
在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了? ...
-
BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...
-
bzoj 2852: 强大的区间 辗转相除
2852: 强大的区间 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 45 Solved: 12[Submit][Status][Discuss] D ...
-
关于C(m,n)%p的故事
序 遥远的\(\mod p\)(\(p\)是质数)大陆有一个恶魔:\[C(m,n)={m!\over n! (m-n)!}\] 于是大家有了各种求逆元的方法.这里MOD = p. 壹 for (int ...
-
Less-css预处理编译
node编译 第一步:https://nodejs.org/en/ 到node官网下载最新的node 第二步:和普通软件一样把node安装好 第三步:运行-cmd,准备安装less 全局安装(整个电 ...
-
基于Python的Web应用开发实践总结
基于Python的Web应用开发学习总结 项目地址 本次学习采用的是Flask框架.根据教程开发个人博客系统.博客界面如图所示. 整个学习过程收获很多,以下是学习总结. 1.virtualenv ...
-
思维导图软件比较-FREEMIND,XMIND,Mindjet Mindmanager
https://www.zhihu.com/question/22094277