//声明:部分内容引自《Java编程思想(第四版)》机械工业出版社
【创建自定义异常】
– 异常与记录日志:
例:
package exceptions;//: exceptions/LoggingExceptions.java
// An exception that reports through a Logger.
import java.util.logging.*;
import java.io.*;
class LoggingException extends Exception {
private static Logger logger =
Logger.getLogger("LoggingException");
public LoggingException() {
StringWriter trace = new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
public class LoggingExceptions {
public static void main(String[] args) {
try {
throw new LoggingException();
} catch(LoggingException e) {
System.err.println("Caught " + e);
}
try {
throw new LoggingException();
} catch(LoggingException e) {
System.err.println("Caught " + e);
}
}
} /* Output: (85% match)
Aug 30, 2005 4:02:31 PM LoggingException <init>
SEVERE: LoggingException
at LoggingExceptions.main(LoggingExceptions.java:19)
Caught LoggingException
Aug 30, 2005 4:02:31 PM LoggingException <init>
SEVERE: LoggingException
at LoggingExceptions.main(LoggingExceptions.java:24)
Caught LoggingException
*///:~
【使用 finally 进行清理】
– 无论异常是否被抛出,finally 子句总能被执行。
– 当要把除内存之外的资源恢复到它们的初始状态时,需要用到 finally 子句。这种需要清理的资源包括:已经打开的文件或网络,在屏幕上画的图形,甚至可以是外部世界的某个开关。
– 在 finally 类内部,从何处返回无关紧要。
【异常的限制】
– 异常限制对构造器不起作用。
– 派生类构造器不能捕获基类构造器抛出的异常。
– 不能基于异常说明来重载方法。
– 一个出现在基类方法的异常说明中的异常,不一定会出现在派生类方法的异常说明里。这恰好与类接口在继承时的情形相反。
【构造器】
– 对于在构造阶段可能会抛出异常,并且要求清理的类,最安全的使用方式是使用嵌套的 try 子句。
【异常匹配】
– 派生类的对象也可以匹配其基类的处理程序。
【其他可选方式】
– 把异常传递给控制台:(没看懂?)
例:
package exceptions;//: exceptions/MainException.java
import java.io.*;
public class MainException {
// Pass all exceptions to the console:
public static void main(String[] args) throws Exception {
// Open the file:
FileInputStream file =
new FileInputStream("MainException.java");
// Use the file ...
// Close the file:
file.close();
}
} ///:~
– 把“被检查的异常”转换为“不检查的异常”
例:
package exceptions;//: exceptions/TurnOffChecking.java
// "Turning off" Checked exceptions.
import java.io.*;
import static net.mindview.util.Print.*;
class WrapCheckedException {
void throwRuntimeException(int type) {
try {
switch(type) {
case 0: throw new FileNotFoundException();
case 1: throw new IOException();
case 2: throw new RuntimeException("Where am I?");
default: return;
}
} catch(Exception e) { // Adapt to unchecked:
throw new RuntimeException(e);
}
}
}
class SomeOtherException extends Exception {}
public class TurnOffChecking {
public static void main(String[] args) {
WrapCheckedException wce = new WrapCheckedException();
// You can call throwRuntimeException() without a try
// block, and let RuntimeExceptions leave the method:
wce.throwRuntimeException(3);
// Or you can choose to catch exceptions:
for(int i = 0; i < 4; i++)
try {
if(i < 3)
wce.throwRuntimeException(i);
else
throw new SomeOtherException();
} catch(SomeOtherException e) {
print("SomeOtherException: " + e);
} catch(RuntimeException re) {
try {
throw re.getCause();
} catch(FileNotFoundException e) {
print("FileNotFoundException: " + e);
} catch(IOException e) {
print("IOException: " + e);
} catch(Throwable e) {
print("Throwable: " + e);
}
}
}
} /* Output:
FileNotFoundException: java.io.FileNotFoundException
IOException: java.io.IOException
Throwable: java.lang.RuntimeException: Where am I?
SomeOtherException: SomeOtherException
*///:~
【异常使用指南】
– 在直到该如何处理的情况下才捕获异常。
– 解决问题并且重新调用产生异常的方法。
– 进行少许修补,然后绕过异常发生的地方继续执行。
– 用别的数据进行计算,以代替方法预计会返回的值。
– 把当前运行环境下能做的事情尽量做完,然后把相同的异常重抛到更高层。
– 把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层。
– 终止程序。
– 进行简化。(前提是异常模式可以使问题变得更简单)
– 让类库和程序更安全。