创建自定义异常

1.在程序中,可能会遇到JDK提供的任何标准异常类都无法充分描述清楚我们想要表达的问题,这种情况下可以创建自己的异常类,即自定义异常类。
2.自定义异常类只需从Exception类或者它的子类派生一个子类即可。
3.自定义异常类如果继承Exception类,则为受检查异常,必须对其进行处理;如果不想处理,可以让自定义异常类继承运行时异常RuntimeException类。
4.习惯上,自定义异常类应该包含2个构造器:一个是默认的构造器,另一个是带有详细信息的构造器。

  1. class MyException extends Exception{
  2. public MyException() {}
  3. public MyException(String msg) { super(msg);}
  4. }
  5. public class FullConstructors {
  6. public static void f() throws MyException{
  7. System.out.println("Throwing MyException from f()");
  8. throw new MyException();
  9. }
  10. public static void g() throws MyException{
  11. System.out.println("Throwing MyException from g()");
  12. throw new MyException("Originated in g()");
  13. }
  14. public static void main(String[] args){
  15. try{
  16. f();
  17. }catch (MyException e){
  18. e.printStackTrace(System.out);
  19. }
  20. try{
  21. g();
  22. }catch (MyException e){
  23. e.printStackTrace(System.out);
  24. // 打印“从方法调用处直到异常抛出处”的方法调用序列。这里,信息被发送到了,并自动地被捕获和显示在输出中。
  25. // e.printStackTrace(); 信息将被输出到标准错误流
  26. }
  27. }
  28. }
  29. /* Output:
  30. Throwing MyException from f()
  31. MyException
  32. at FullConstructors.f(FullConstructors.java:9)
  33. at FullConstructors.main(FullConstructors.java:17)
  34. Throwing MyException from g()
  35. MyException: Originated in g()
  36. at FullConstructors.g(FullConstructors.java:13)
  37. at FullConstructors.main(FullConstructors.java:22)
  38. */

异常与记录日志

使用java.util.logging工具将输出记录到日志中。

  1. import java.io.PrintWriter;
  2. import java.io.StringWriter;
  3. import java.util.logging.*;
  4. class LoggingException extends Exception{
  5. private static Logger logger= Logger.getLogger("LoggingException");
  6. public LoggingException() {
  7. StringWriter trace = new StringWriter();
  8. printStackTrace(new PrintWriter(trace));
  9. logger.severe(trace.toString());
  10. }
  11. }
  12. public class LoggingExceptions {
  13. public static void main(String[] args){
  14. try{
  15. throw new LoggingException();
  16. }catch (LoggingException e){
  17. System.err.println("Caught "+e);
  18. }
  19. try{
  20. throw new LoggingException();
  21. }catch (LoggingException e){
  22. System.err.println("Caught "+e);
  23. }
  24. }
  25. }
  26. /* Output:
  27. Dec 16, 2019 4:53:19 PM LoggingException <init>
  28. SEVERE: LoggingException
  29. at LoggingExceptions.main(LoggingExceptions.java:17)
  30. Caught LoggingException
  31. Dec 16, 2019 4:53:19 PM LoggingException <init>
  32. SEVERE: LoggingException
  33. at LoggingExceptions.main(LoggingExceptions.java:22)
  34. Caught LoggingException
  35. */
  1. import java.io.PrintWriter;
  2. import java.io.StringWriter;
  3. import java.util.logging.*;
  4. public class LoggingExceptions2 {
  5. private static Logger logger= Logger.getLogger("LoggingException2");
  6. static void LogException(Exception e){
  7. StringWriter trace = new StringWriter();
  8. e.printStackTrace(new PrintWriter(trace));
  9. logger.severe(trace.toString());
  10. }
  11. public static void main(String[] args){
  12. try{
  13. throw new NullPointerException();
  14. }catch (NullPointerException e){
  15. LogException(e);
  16. }
  17. }
  18. }
  19. /* Output:
  20. Dec 16, 2019 4:59:49 PM LoggingExceptions2 LogException
  21. SEVERE: java.lang.NullPointerException
  22. at LoggingExceptions2.main(LoggingExceptions2.java:23)
  23. */

如果要记录catch块中所发生异常,最好不要手动解析堆栈跟踪并将输出发送到 System.err(),而是使用java.util.logging包中的日志记录工具将输出发送到文件。

  1. try {
  2. Handler handler = new FileHandler("OutFile.log");
  3. Logger.getLogger("").addHandler(handler);
  4. } catch (IOException e) {
  5. Logger logger = Logger.getLogger("package.name");
  6. StackTraceElement elements[] = e.getStackTrace();
  7. for (int i = 0, n = elements.length; i < n; i++) {
  8. logger.log(Level.WARNING, elements[i].getMethodName());
  9. }
  10. }