java exception和error异常和错误

2023-10-20 10:48:39 浏览数 (1)

体系

我们在使用java的时,经常面对和处理的是异常(Exception)很少处理错误。因为如果是错误级别的往往都是比较底层的非代码层面的问题。 但是这两个的区别,有必搞清楚。 这两个是一对难兄难弟,有问题的时候都会出现这两兄弟。

通过图片可以直观的看出它们的体系,这图点开看比较清楚:

异常 Exception

这个是最常遇见的问题,主要是由于编码原因异常的问题。 我们开发过程中常见的是运行时异常,就是字面意思,运行时才知道的异常,运行时,才会有可能抛出来的异常。 那相对的,就有非运行时的异常,就是不需要运行,也能知道是异常。

而异常当中,又有几个概念,这些概念性的东西,只是帮助分类和理解,使用场景可以说是经常遇见,分别是:

两种异常:

  • 运行时异常 RuntimeException
  • 异常 Exception

运行时异常 RuntimeException

只有运行时才会知道是否有异常,比如下面这段代码会不会抛常异?

代码语言:javascript复制
public class Test {

  public void test(int a, int b) {
    int c = a / b;
  }
}

会不会抛异常,用眼睛看很合理,没毛病,但是问题是你不知道ab分别会传什么值进来。 如果传:

a = 9; b = 3;

没问题,但是如果传:

a = 1; b = 0;

就抛异常了,上面那段代码不在运行时,你根本不知道会不会抛异常,所以只有运行时才会知道,就叫运行时异常。

处理RuntimeException的原则是:如果出现 RuntimeException,那么一定是程序员的错误。 例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。 其他(IOException等等)checked 异常一般是外部错误,例如试图从文件尾后读取数据、网络中断等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

常见的运行时异常有:

  • NullPointerException: 空指针异常
  • IndexOutOfBoundsException: 下标越界异常
  • IllegalArgumentException: 传递非法参数异常
  • ClassCastException: 类型强制转换异常
  • NumberFormatException: String转换为指定的数字类型异常
  • ArithmeticException: 算术运算异常 如除数为0

异常 Exception

除了上面的 运行时异常 RuntimeException之外,其他的异常都是 Exception 的子类,都是检查时异常Checked Exception。 这种异常程序无法恢愎,运行出现时会导至程序终止,如空指针。 IOException、SQLException,这些都是异常。 上面已经总结了。

错误 Error

代码运行中不是由代码引起的问题,是由外部资源异至的JVM错误,一般就归到错误里,通常由JVM处理问题,有的错误JVM也处理不了。 Error 是可以被捕获的,但是程序都已经出现了JVM都无法处理的错误,捕获的意思除了打印详情外,还让程序继续执行,比如 OOM 这种错误,还有必要执行吗,生产环境,这样做可能会造成经济损失,所以完全不建议捕获错误。

举个例子,手动制造内存溢出,使JVM产生错误后退出。

JVM 启动参数:

-Xms20M -Xmx20M -Xmn20M -XX: HeapDumpOnOutOfMemoryError

测试代码:

代码语言:javascript复制
public class TestOOM {

  public static void main(String[] args) {
    test1();
  }

  public static void test1() {
    List<String> list = new ArrayList<String>();
    try {
      while (true) {
        list.add(new String());
      }
    } catch (Exception exception) {
      System.out.println("output...");
    }
  }
}

结果: JVM 遇到错误后,直接就退出了,catch 里的语句没有打印。

checked exception 和 unchecked exception

这两个就是字面上的意思:

  • 已检查异常 checked exception
  • 未检查异常 unchecked exception

捕获错误 不推荐

还是那句话,JVM都Error了,再让程序运行,没有意义,不能保证JVM能恢复正常。

代码语言:javascript复制
package org.liukai.check;

public class TestCatchError extends Error {
  private static final long serialVersionUID = -351488225420878020L;

  public TestCatchError() {
    super();
  }

  public TestCatchError(String msg) {
    super(msg);
  }

  public static void main(String[] args) {
    try {
      throw new TestCatchError("test catch error");
    } catch (Throwable t) {
      System.out.println("step in the catch ~");
      t.printStackTrace();
    }
  }
}

checked exceptions

需要在代码中显式地在方法签名中加上throws语句,或用throws-catch语句处理,否则编译不通过。 比如在使用IO类时,JDK一定会要求加上throws-catch,因为这些方法JDK已经throws了,也就是 checked 了,不加不行。

unchecked exceptions

不需要在代码中显式地处理,事实上是不鼓励显式的处理,因为这样的代码是多余的。 我们写的大部分代码都是 unchecked ,因为在代码中不可能每一行、每一个代码块都是添加 try-catch,这样直接设计JDK全局加上就完了,还需要程序员去关心checked不checked,我们只需要在可能出现的地方加上try-catch就可以了,这种问题完全依靠代码健状性即可。

总结

异常可以被补获,而错误不能,会异常JVM异常退出。 一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。 对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和和预防,遇到这样的错误,建议让程序终止。

0 人点赞