error是什么意思(还不理解 Error 和 Exception 吗,看这篇就够了)

还不了解 Error 和 Exception 吗,看这篇就够了


在 Java 中的基本理念是 布局不佳的代码不克不及运转,发觉错误的抱负时期是在编译时期,由于你不必运转步骤,只是依靠着对 Java 基本理念的了解就能发觉成绩。但是编译期并不克不及找出一切的成绩,有一些 NullPointerException 和 ClassNotFoundException 在编译期找不到,这些特别是 RuntimeException 运转时特别,这些特别屡屡在运转时才干被发觉。

我们写 Java 步骤常常会显现两种成绩,一种是 java.lang.Exception ,一种是 java.lang.Error,都用来表现显现了特别情况,底下就针对这两种看法举行了解。

熟悉 Exception

Exception 位于 java.lang 包下,它是一种顶级接口,承继于 Throwable 类,Exception 类及其子类都是 Throwable 的构成条件,是步骤显现的公道情况。

在熟悉 Exception 之前,有必要先了解一下什么是 Throwable。

什么是 Throwable

Throwable 类是 Java 言语中一切错误(errors)和特别(exceptions)的父类。仅有承继于 Throwable 的类大概其子类才干够被抛出,另有一种办法是带有 Java 中的 @throw 注解的类也可以抛出。

在Java标准中,对非受查特别和受查特别的界说是如此的:

The unchecked exception classes are the run-time exception classes and the error classes.

The checked exception classes are all exception classes other than the unchecked exception classes. That is, the checked exception classes are Throwable and all its subclasses other than RuntimeException and its subclasses and Errorand its subclasses.

也就是说,除了 RuntimeException 和其子类,以及error和其子类,别的的一切特别都是 checkedException。

那么,依照这种逻辑干系,我们可以对 Throwable 及其子类举行归类分析

可以看到,Throwable 位于特别和错误的最顶层,我们查察 Throwable 类中发觉它的办法和属性有很多,我们只讨论此中几个比力常用的

// 前往抛出特别的具体信息 public string getMessage(); public string getLocalizedMessage(); //前往特别产生时的扼要形貌 public public String toString(); // 打印特别信息到标准输入流上 public void printStackTrace(); public void printStackTrace(PrintStream s); public void printStackTrace(PrintWriter s) // 纪录栈帧的的如今形态 public synchronized Throwable fillInStackTrace();

别的,由于 Throwable 的父类也是 Object,以是常用的办法另有承继其父类的getClass() 和 getName() 办法。

稀有的 Exception

底下我们回到 Exception 的探究上去,如今你晓得了 Exception 的父类是 Throwable,并且 Exception 有两种特别,一种是 RuntimeException ;一种是 CheckedException,这两种特别都应该去捕捉。

底下列出了一些 Java 中稀有的特别及其分类,这块口试官也约莫让你举出几个稀有的特别情况并将其分类

RuntimeException


UncheckedException



与 Exception 有关的 Java 紧张字

那么 Java 中是怎样处理这些特别的呢?在 Java 中有这几个紧张字 throws、throw、try、finally、catch 底下我们分散来探究一下

throws 和 throw

在 Java 中,特别也就是一个目标,它可以被步骤员自界说抛出大概使用步骤抛出,必需借助于 throws 和 throw 语句来界说抛出特别。

throws 和 throw 通常是成对显现的,比如

static void cacheException() throws Exception{ throw new Exception(); }

throw 语句用在办法体内,表现抛出特别,由办法体内的语句处理。throws 语句用在办法声明后方,表现再抛出特别,由该办法的调用者来处理。

throws 主要是声明这个办法会抛出这品种型的特别,使它的调用者晓得要捕捉这个特别。throw 是具体向外抛特别的举措,以是它是抛出一个特别实例。

try 、finally 、catch

这三个紧张字主要有底下几种组合办法 try...catch 、try...finally、try...catch...finally

try...catch 表现对某一段代码约莫抛出特别举行的捕捉,如下

static void cacheException() throws Exception{ try { System.out.println("1"); }catch (Exception e){ e.printStackTrace(); } }

try...finally 表现对一段代码不管实行情况怎样,都市走 finally 中的代码

static void cacheException() throws Exception{ for (int i = 0; i < 5; i++) { System.out.println("enter: i=" + i); try { System.out.println("execute: i=" + i); continue; } finally { System.out.println("leave: i=" + i); } } }

try...catch...finally 也是一样的,表现对特别捕捉后,再走 finally 中的代码逻辑。

JDK1.7 使用 try...with...resources 优雅关闭资源

Java 类库中有很多资源必要经过 close 办法举行关闭。好比 InputStream、OutputStream,数据库毗连目标 Connection,MyBatis 中的 SqlSession 会话等。作为开发职员常常会忽略掉资源的关闭办法,招致内存泄漏。

依据履历,try-finally语句是确保资源会被关闭的最佳办法,就算特别大概前往也一样。try-catch-finally 寻常是如此来用的

static String firstLineOfFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); }finally { br.close(); } }

如此看起来代码照旧比力划一,但是当我们添加第二个必要关闭的资源的时分,就像底下如此

static void copy(String src,String dst) throws Exception{ InputStream is = new FileInputStream(src); try { OutputStream os = new FileOutputStream(dst); try { byte[] buf = new byte[100]; int n; while ((n = is.read()) >= 0){ os.write(buf,n,0); } }finally { os.close(); } }finally { is.close(); } }

如此以为这个办法以前变得痴肥起来了。

并且这种写法也存在诸多成绩,即使 try - finally 可以准确关闭资源,但是它不克不及制止特别的抛出,由于 try 和 finally 块中都约莫有特别的产生。

好比说你正在读取的时分硬盘毁坏,这个时分你就无法读取文件和关闭资源了,此时会抛出两个特别。但是在这种情况下,第二个特别会抹掉第一个特别。在特别堆栈中也无法找到第一个特别的纪录,怎样办,岂非像如此来捕捉特别么?

static void tryThrowException(String path) throws Exception { BufferedReader br = new BufferedReader(new FileReader(path)); try { String s = br.readLine(); System.out.println("s = " + s); }catch (Exception e){ e.printStackTrace(); }finally { try { br.close(); }catch (Exception e){ e.printStackTrace(); }finally { br.close(); } } }

这种写法,固然能处理特别抛出的成绩,但是种种 try-cath-finally 的嵌套会让代码变得十分痴肥。

Java7 中引入了try-with-resources 语句时,一切这些成绩都能取得处理。要使用 try-with-resources 语句,起主要完成 AutoCloseable 接口,此接口包含了单个前往的 close 办法。Java 类库与三方类库中的很多类和接口,如今都完成大概扩展了 AutoCloseable 接口。假如编写了一个类,它代表的是必需关闭的资源,那么这个类应该完成 AutoCloseable 接口。

java 引入了 try-with-resources 声明,将 try-catch-finally 简化为 try-catch,这但是是一种语法糖,在编译时会举行转化为 try-catch-finally 语句。

底下是使用 try-with-resources 的第一个典范

/** * 使用try-with-resources 改写示例一 * @param path * @return * @throws IOException */ static String firstLineOfFileAutoClose(String path) throws IOException { try(BufferedReader br = new BufferedReader(new FileReader(path))){ return br.readLine(); } }

使用 try-with-resources 改写步骤的第二个示例

static void copyAutoClose(String src,String dst) throws IOException{ try(InputStream in = new FileInputStream(src); OutputStream os = new FileOutputStream(dst)){ byte[] buf = new byte[1000]; int n; while ((n = in.read(buf)) >= 0){ os.write(buf,0,n); } } }

使用 try-with-resources 不仅使代码变得普通易懂,也更容易诊断。以firstLineOfFileAutoClose办法为例,假如调用 readLine() 和 close() 办法都抛出特别,后一个特别就会被克制,以保存第一个特别。

特别处理的准则

我们在平常处理特别的代码中,应该依照三个准则

  • 不要捕捉相似 Exception 之类的特别,而应该捕捉相似特定的特别,好比 InterruptedException,便利排查询题,并且也可以让其他人接办你的代码时,会变小骂你的次数。
  • 不要生吞特别。这是特别处理中要特别注意的事变,由于很约莫会十分难以正常完毕情况。假如我们不把特别抛出来,大概也没有输入到 Logger 日志中,步骤约莫会在后方以不成控的办法完毕。
  • 不要在函数式编程中使用 checkedException。

什么是 Error

Error 是步骤无法处理的错误,表现运利用用步骤中较严峻成绩。大大多错误与代码编写者实行的利用不关,而表现代码运转时 JVM(Java 假造机)显现的成绩。这些错误是不成反省的,由于它们在使用步骤的控制和处理才能之 外,并且绝大大多是步骤运转时不允许显现的情况,好比 OutOfMemoryError 和 StackOverflowError特别的显现会有几种情况,这里必要先先容一下 Java 内存模子 JDK1.7。

此中包含两局部,由一切线程共享的数据区和线程断绝的数据区构成,在外表的 Java 内存模子中,仅有步骤计数器是不会产生 OutOfMemoryError 情况的地区,步骤计数器控制着盘算机指令的分支、循环、跳转、特别处理和线程规复,并且步骤计数器是每个线程公有的。

什么是线程公有:表现的就是各条线程之间互不影响,独立存储的内存地区。

假如使用步骤实行的是 Java 办法,那么这个计数器纪录的就是假造机字节码指令的地点;假如正在实行的是 Native 办法,这个计数器值则为空(Undefined)。

除了步骤计数器外,其他地区:办法区(Method Area)、假造机栈(VM Stack)、本场合法栈(Native Method Stack) 和 堆(Heap) 都是约莫产生 OutOfMemoryError 的地区。

  • 假造机栈:假如线程哀求的栈深度大于假造机栈所允许的深度,将会显现 StackOverflowError 特别;假如假造机动态扩展无法哀求到充足的内存,将显现 OutOfMemoryError。
  • 本场合法栈和假造机栈一样
  • 堆:Java 堆可以处于物理上不一连,逻辑上一连,就像我们的磁盘空间一样,假如堆中没有内存完成实例分派,并且堆无法扩展时,将会抛出 OutOfMemoryError。
  • 办法区:办法区无法满意内存分派需求时,将抛出 OutOfMemoryError 特别。

一道经典的口试题

一道十分经典的口试题,NoClassDefFoundError 和 ClassNotFoundException 有什么区别

在类的加载历程中, JVM 大概 ClassLoader 无法找到对应的类时,都约莫会惹起这两种特别/错误,由于不同的 ClassLoader 会从不同的场合加载类,偶尔是错误的 CLASSPATH 类途径招致的这类错误,偶尔是某个库的 jar 包缺失引发这类错误。NoClassDefFoundError 表现这个类在编译时期存在,但是在运转时却找不到此类,偶尔静态初始化块也会招致 NoClassDefFoundError 错误。

ClassLoader 是类途径装载器,在Java 中,类途径装载器一共有三种两类

一种是假造机自带的 ClassLoader,分为三种

启动类加载器(Bootstrap) ,卖力加载 $JAVAHOME/jre/lib/rt.jar扩展类加载器(Extension),卖力加载 $JAVAHOME/jre/lib/ext/*.jar使用步骤类加载器(AppClassLoader),加载如今使用的 classpath 的一切类

第二种是用户自界说类加载器

Java.lang.ClassLoader 的子类,用户可以定制类的加载办法。

另一方面,ClassNotFoundException 与编译时期不关,当你实验在运转时使用反射加载类时,ClassNotFoundException 就会显现。

简而言之,ClassNotFoundException 和 NoClassDefFoundError 都是由 CLASSPATH 中短少类惹起的,通常是由于短少 JAR 文件而惹起的,但是假如 JVM 以为使用运转时找不到相应的引用,就会抛出 NoClassDefFoundError 错误;当你在代码中体现的加载类好比 Class.forName() 调用时却没有找到相应的类,就会抛出
java.lang.ClassNotFoundException。

  • NoClassDefFoundError 是 JVM 惹起的错误,是 unchecked,未经反省的。因此不会使用 try-catch 大概 finally 语句块;别的,ClassNotFoundException 是受检特别,因此必要 try-catch 语句块大概 try-finally 语句块包抄,不然会招致编译错误。
  • 调用 Class.forName()、ClassLoader.findClass() 和 ClassLoader.loadClass() 等办法时约莫会惹起 java.lang.ClassNotFoundException,如图所示

  • NoClassDefFoundError 是链接错误,产生在链接阶段,当剖析引用找不到对应的类,就会触发;而 ClassNotFoundException 是产生在运转时的特别。

文章参考:

https://www.java67.com/2012/12/noclassdeffounderror-vs-classnotfoundexception-java.html

《极客时间-Java中心武艺 36 讲》

《深化了解 Java 假造机》第二版

《Effective Java 第三版》

https://www.cnblogs.com/xiohao/p/3547443.html

https://blog.csdn.net/qq_29229567/article/details/80773970

https://blog.csdn.net/riemann_/article/details/87522352

《Java编程头脑》

https://www.cnblogs.com/xz816111/p/8466048.html

https://docs.oracle.com/javase/specs/jls/se9/html/jls-11.html#jls-11.1.1

jdk 1.8 源码正文

内容底部广告位(手机)
标签:

管理员
草根站长管理员

专注网站优化+网络营销,只做有思想的高价值网站,只提供有担当的营销服务!

上一篇:product(productive)
下一篇:返回列表

相关推荐