违例差错控制
来源:互联网 发布:深圳龙岗大运软件小镇 编辑:程序博客网 时间:2024/04/30 01:32
说明:捕获错误最理想情况下是在编译期间捕获,但是并不是所有的错误都能够在编译期间捕获,有些错误必须等到运行期间才能发现,检测到运行期间发生的错误后该如何通知及处理?如果每次调用一个方法时都要细致地检查错误,代码可读性大大降低。
违例:一种例外情况,在问题发生的时候,我们可能不知道该如何解决,但一定知道的是程序不能就这样一直执行下去,需要将错误报告出去,并采取一定的措施。本地可能没有足够多的信息,需要将其抛出交给上一级处理。
好处:我们在一个地方处理问题,不用因为检查一个特定的错误,在多个地方进行控制。
下面介绍:正确控制违例以及如何生成自己的违例
1.基本违例:
1.1违例条件:出现什么问题时应该中止方法或作用域的继续
1.2违例过程:违例发生时,在内存堆里使用new创建了一个违例对象,停止当前执行路径,从当前环境中释放出违例对象句柄,违例控制机制接管一切,使我们从错误产生地方迁移到其他地方解决。
2.违例捕获:
若某个方法产生违例,必须保证该违例能被捕获,并获得正确对待。掷出一个违例时,违例控制器会自动搜索自变量与违例类型相符的第一个控制器,并不在搜索其他违例控制器。
try{可能产生违例的地方}生成的违例在catch中中止catch(Exception1 exception1){处理特定类型的违例}catch(Exception2 exception2){处理特定类型的违例}...}.catch(Exceptionn Exceptionn){处理特定类型的违例}抛出所有潜在的违例类型void f() throws Exception1,...Exceptionn{..}
3.重新掷出违例
掷出当前违例句柄,违例进入更高一级违例控制器中,同一try块中的catch从句仍然被忽略。使用throw掷出当前句柄e,只有在高一级catch块中捕获。
package com.zd.java.exception;/** * 将当前堆栈的信息填充到原来的违例中 * Created by ZD on 2017/10/10. */public class Rethrowing { public static void f() throws Exception{ System.out.println("originating the exception in f()"); throw new Exception("throw from f()"); } public static void g() throws Throwable{ try{ f(); }catch (Exception e){ System.out.println("Inside g(),e.printStackTrace()"); e.printStackTrace(); throw e; } } public static void main(String[] args) throws Throwable{ try{ g(); }catch (Exception e){ System.out.println("caught in main,e.printStackTrace()"); e.printStackTrace(); } }}打印结果:originating the exception in f()java.lang.Exception: throw from f()Inside g(),e.printStackTrace() at com.zd.java.exception.Rethrowing.f(Rethrowing.java:11) at com.zd.java.exception.Rethrowing.g(Rethrowing.java:16) at com.zd.java.exception.Rethrowing.main(Rethrowing.java:26)caught in main,e.printStackTrace()java.lang.Exception: throw from f() at com.zd.java.exception.Rethrowing.f(Rethrowing.java:11) at com.zd.java.exception.Rethrowing.g(Rethrowing.java:16) at com.zd.java.exception.Rethrowing.main(Rethrowing.java:26)
4.创建自己的违例
经常需要创建自己的违例,指出自己所写的库可能存在的问题,创建自己的违例类,必须从一个现有的违例类型继承,最好在含义上与新违例类似。
java.lang.Exception–>程序能捕获的基本违例,其他违例基本都是从此衍生出去的,也有程序不是从Exception衍生的,比如IO有关的都是从IOException衍生的。
package com.zd.java.exception;/** * 创建自己的违例时,可以采取更多的操作,可添加额外的构建器及成员 * Created by ZD on 2017/10/10. */public class Inheriting2 { public static void f() throws MyException2{ System.out.println("throwing myexception2 from f()"); throw new MyException2(); } public static void g() throws MyException2{ System.out.println("throwing myexception2 from g()"); throw new MyException2("originated in g()"); } public static void h() throws MyException2{ System.out.println("throwing myexception2 from h()"); throw new MyException2("originated in h()"); } public static void main(String[] args){ try{ f(); }catch (MyException2 e){ e.printStackTrace(); } try{ g(); }catch (MyException2 e){ // e.printStackTrace(); } try{ h(); }catch (MyException2 e){ // e.printStackTrace(); System.out.println("e.val()="+e.val()); } }}class MyException2 extends Exception{ private int i; public MyException2(){} public MyException2(String msg){ super(msg); } public MyException2(String msg,int x){ super(msg); i = x; } public int val(){ return i; }}com.zd.java.exception.MyException2 at com.zd.java.exception.Inheriting2.f(Inheriting2.java:10) at com.zd.java.exception.Inheriting2.main(Inheriting2.java:25)throwing myexception2 from f()throwing myexception2 from g()throwing myexception2 from h()e.val()=0
5.违例的限制
覆盖一个方法时,只能产生在方法基础类版本中声明的违例,重写方法中可以不声明违例,但不能声明未在基类方法中声明的违例。
package com.zd.java.exception;/** * Created by ZD on 2017/10/11. */class BaseballException extends Exception{}class Foul extends BaseballException{}class Strike extends BaseballException{}abstract class Inning{ Inning() throws BaseballException{} void event() throws BaseballException{} abstract void atBat() throws Strike,Foul; void walk(){};}class StromException extends Exception{}class RainedOut extends StromException{}class PopFoul extends Foul{}interface Storm{ void event() throws RainedOut; void rainHard() throws RainedOut;}public class StormyInning extends Inning implements Storm { StormyInning() throws RainedOut,BaseballException{}// /**// * 基类方法walk未声明抛出PopFoul异常,子类方法不可抛出// * @throws PopFoul// */ //void walk() throws PopFoul{}// /**// * 实现接口的event方法,基类中也有event方法,相当于重写了基类的event方法,// * 在基类event方法中没有声明RainedOut异常// * @throws RainedOut// */// @Override// public void event() throws RainedOut {// } /** * 实现接口方法,重写了基类中方法,接口方法声明异常与基类方法声明异常不一致,可以选择不抛出异常 */ @Override public void event() { } @Override public void rainHard() throws RainedOut { } /** * 重写方法可以抛出异常的子类 * @throws PopFoul */ @Override void atBat() throws PopFoul{ } public static void main(String[] args){ try{ StormyInning si = new StormyInning(); si.atBat(); }catch (PopFoul popFoul) { popFoul.printStackTrace(); }catch (RainedOut rainedOut) { rainedOut.printStackTrace(); } catch (BaseballException e) { e.printStackTrace(); } try{ Inning i = new StormyInning(); i.atBat(); }catch (RainedOut rainedOut) { rainedOut.printStackTrace(); } catch (Strike strike) { strike.printStackTrace(); } catch (Foul foul) { foul.printStackTrace(); } catch (BaseballException e) { e.printStackTrace(); } }}
6.finally
无论一个违例是否发生,都想要执行特定的代码。
try{可能产生违例的地方}生成的违例在catch中中止catch(Exception1 exception1){处理特定类型的违例}catch(Exception2 exception2){处理特定类型的违例}...}.catch(Exceptionn Exceptionn){处理特定类型的违例}finally{无论何种情况,一定会执行的}
finally使用过程中需要注意,在构建器中使用违例控制时,比如打开文件,finally就不是关闭文件位置的好选择。
package com.zd.java.exception;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
/**
* Created by ZD on 2017/10/11.
*/
class InputFile{
private BufferedReader in;
InputFile(String filename) throws Exception{
try{
in = new BufferedReader(new FileReader(filename));
}catch (FileNotFoundException e){
System.out.println(“could not open “+filename);
throw e;
}catch (Exception e){
try{
in.close();
System.out.println(“in.close()”);
}catch (IOException e2){
System.out.println(“in.close() unsuccessful”);
}
throw e;
}finally {
//do not close it here
}
}
String getLine() {
String s;
try{
s = in.readLine();
}catch (IOException e){
System.out.println(“readLine() unsucessful”);
s = “failed”;
}
return s;
}
void cleanuo(){
try{
in.close();
}catch (IOException e){
System.out.println(“in.close() unsucessful”);
}
}
}
public class Cleanup {
public static void main(String[] args){
try{
InputFile file = new InputFile(“Cleanup.java”);
String s;
int i = 1;
while ((s = file.getLine()) != null){
System.out.println(“”+ i++ + “: “+s);
}
file.cleanuo();
}catch (Exception e){
System.out.println(“caught in main,e.printStackTrace()”);
e.printStackTrace();
}
}
}
执行结果:
could not open Cleanup.java
caught in main,e.printStackTrace()
java.io.FileNotFoundException: Cleanup.java (系统找不到指定的文件。)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:138)
at java.io.FileInputStream.(FileInputStream.java:93)
at java.io.FileReader.(FileReader.java:58)
at com.zd.java.exception.InputFile.(Cleanup.java:17)
at com.zd.java.exception.Cleanup.main(Cleanup.java:59)
7.违例丢失
违例可能会丢失,在使用finally从句中存在违例丢失情况
**
package com.zd.java.exception;/** * 违例可能会丢失 * VeryImportantException违例丢失 * Created by ZD on 2017/10/11. */class VeryImportantException extends Exception{ public String toString(){ return "a very important exception"; }}class HoHumException extends Exception{ public String toString(){ return "a trivial exception"; }}public class LostMessage { void f() throws VeryImportantException{ throw new VeryImportantException(); } void dispose() throws HoHumException{ throw new HoHumException(); } public static void main(String[] args) throws Exception{ LostMessage lm = new LostMessage(); try{ lm.f(); }finally { lm.dispose(); } }}输出结果:Exception in thread "main" a trivial exception at com.zd.java.exception.LostMessage.dispose(LostMessage.java:29) at com.zd.java.exception.LostMessage.main(LostMessage.java:38)
**
- 违例差错控制
- 违例差错控制
- 第9章 违例差错控制
- 违例差错控制需要注意的地方
- JAVA编程思想:第9章 违例差错控制
- 24.JAVA编程思想——违例差错控制
- Thinking in Java 第9章 违例差错控制 总结
- JAVA编程思想学习 — 第九章 (违例差错控制)
- java编程思想(第四版)_第9章 违例差错控制
- 差错控制
- Java违例控制 总结
- Java违例控制总结
- Java违例控制
- 差错控制编码
- 3.3 差错控制
- TCP差错控制
- 差错控制-CRC校验
- TCP协议之差错控制
- DBA的价值和定位
- Socket
- 支付宝支付的大致流程
- Java-IO(五)——字符流进阶及BufferedWriter、BufferedReader
- JDBC
- 违例差错控制
- C语言基础知识学习(二)
- list 集合排序,java8新特性,学习一下
- 用JavaScript写的无缝滚动的小案例
- 【HTML5】——SVG基础
- TOP100summit2017:微博如何做到1小时增加一千台服务器应对鹿晗恋情带来的流量暴增
- Ubuntu用sudo apt-get update出错:E: Problem executing scripts APT::Update::Post-Invoke-Success
- BigDecimal页面展示
- Django的全文检索功能(二):whoosh搜索引擎