异常处理方法

  对于非运行时异常(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异常知识点汇总的更多相关文章

  1. Java面试知识点汇总

    Java面试知识点汇总 置顶 2019年05月07日 15:36:18 温柔的谢世杰 阅读数 21623 文章标签: 面经java 更多 分类专栏: java 面试 Java面试知识汇总   版权声明 ...

  2. java异常知识点整理

    异常处理机制:捕获异常(try-catch-finally)和声明抛弃异常(throw); 所有的异常类都直接或者间接地继承于Throwable类: java异常分为可查异常和不可查异常两种.可查异常 ...

  3. java io知识点汇总FIle类

    1.路径分隔符问题: 因为java有跨平台行,而在windows和linux中的目录分隔符是不同的.windows是"\" 而linux是"/"  所以必须想办 ...

  4. java小知识点汇总

    1.ConcurrentHashMap使用segment来分段和管理锁,segment继承自ReentrantLock,因此ConcurrentHashMap使用ReentrantLock来保证线程安 ...

  5. Java 面试知识点汇总

    OOP:(Object Oriented Programming )面向对象编程 重用性.灵活性和扩展性 高内聚.低耦合 面向过程编程与面向对象编程的区别:举例,自己做饭吃与去饭馆吃,去饭馆只需要知道 ...

  6. JAVA学习知识点汇总

    异常处理 1.在异常处理中,如果子类覆盖了父类的一个方法,子类方法中声明的已检查异常不能比父类方法声明的异常更通用,即子类方法可以抛出更特定的异常(不超过父类方法声明的异常范围,即由父类方法声明异常派 ...

  7. Java WebService 知识点汇总

    java webservice 获取传入IP axis.jar    servlet.jar MessageContext mMsgContext = MessageContext.getCurren ...

  8. java多线程知识点汇总(一)多线程基础

    1.什么叫多线程程序? 答:一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序. java编写的程序都是多线程的,因为最少有俩线程,main主线程和gc线程. ...

  9. Java 常用知识点汇总(数据类型之间转换、字符串的相关操作-截取、转换大小写等)

    1.Java四类八种数据类型 byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围- ...

随机推荐

  1. 嵌入式 探讨父子线程、进程终止顺序不同产生的结果_skdkjxy_新浪博客

    嵌入式 探讨父子线程.进程终止顺序不同产生的结果 Linux下编程,线程.进程退出顺序问题纷纷扰扰,如果父进程/线程先于子进程/线程终止,系统会做什么处理呢?反之,如果子进程/线程先于父进程/线 程终 ...

  2. ***四种参数传递的形式——URL,超链接,js,form表单

    什么时候用GET,  查,删 什么时候用POST,增,改  (特列:登陆用Post,因为不能让用户名和密码显示在URL上) 4种get传参方式 <html xmlns="http:// ...

  3. 开源框架:SDWebImage

    http://blog.csdn.net/uxyheaven/article/details/7909373 SDWebImage是我搞iOS以来少数佩服的框架,膜拜一下作者.真的写的非常棒! 这套开 ...

  4. 【PAT】1016 部分A+B(15 分)

    1016 部分A+B(15 分) 正整数 A 的“D​A​​(为 1 位整数)部分”定义为由 A 中所有 D​A​​ 组成的新整数 P​A​​.例如:给定 A=3862767,D​A​​=6,则 A  ...

  5. JavaScript event loop事件循环 macrotask与microtask

    macrotask  姑且称为宏任务,在很多上下文也被简称为task.例如: setTimeout, setInterval, setImmediate, I/O, UI rendering. mic ...

  6. python日期格式转换小记

    utc格林时间==>东八区北京时间 原始日期格式: utctime = ‘2016-07-26 10:08:29’ localtime = (datetime.datetime.fromtime ...

  7. 因为修改linux selinux修改错误产生的问题及解决办法

    会出现这个错误: not syncing attempted to kill init 解决办法是: 开机后一直按e 然后按这个修改: https://www.deep-silver.com/kern ...

  8. [CodeForces - 678F] Lena and Queries 线段树维护凸包

    大致题意: 给出三种操作 1.往平面点集中添加一个点 2.删除第i次添加的点 3.给出一个q,询问平面点集中的q*x+y的最大值 首先对于每个询问,可将z=q*x+y转化为y=z-q*x,即过点(x, ...

  9. 2018年全国多校算法寒假训练营练习比赛(第一场)J - 闯关的lulu

    链接:https://www.nowcoder.com/acm/contest/67/J来源:牛客网 题目描述 勇者lulu某天进入了一个高度10,000,000层的闯关塔,在塔里每到一层楼,他都会获 ...

  10. zoj 3983 Crusaders Quest 思维+枚举

    题目链接 这道题意思是: 给你一个长度为9的字符串,且只有3个a.3个g.3个o 问,你可以选择删除一段连续的串或者单个的字符也可以不删,最多会出现几个三子相连的子串 比如:agoagoago只有将两 ...