【SE】:Java异常、由浅入深、由原理入面试题

【SE】:Java异常、由浅入深、由原理入面试题,第1张

【SE】:Java异常、由浅入深、由原理入面试题

      • Java异常架构与关键字
      • 异常处理机制
        • 捕获异常:try-catch-finally
          • try-catch的使用规则:
          • try-catch-finally中finally的使用:
        • 声明异常:throws
          • throws的使用规则:
          • 重写方法声明抛出异常的原则:
        • 手动抛出异常:throw
        • 如何选择异常类型?
      • 用户自定义异常类
      • 异常总结:
      • Java异常常见面试题
          • Error 和 Exception 区别是什么?
          • 运行时异常和一般异常(受检异常)区别是什么?
          • JVM 是如何处理异常的?
          • throw 和 throws 的区别是什么?
          • final、finally、finalize 有什么区别?
          • NoClassDefFoundError 和 ClassNotFoundException 区别?
          • try-catch-finally 中哪个部分可以省略?
          • try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?
          • 类 ExampleA 继承 Exception,类 ExampleB 继承ExampleA,那如下代码会输出啥?
          • 《Java 编程思想》示例输出什么?
          • 常见的 RuntimeException 有哪些?
      • JAVA异常处理的实践技巧:
          • 在 finally 块中清理资源或者使用 try-with-resource 语句
          • 优先明确的异常
          • 对异常进行文档说明
          • 使用描述性消息抛出异常、优先捕获最具体的异常
          • 不要捕获 Throwable 类
          • 不要忽略异常
          • 不要记录并抛出异常(最常被忽略的最佳实践)
          • 包装异常时不要抛弃原始的异常
          • 不要使用异常控制程序的流程
          • 使用标准异常
          • 异常会影响性能
      • 参考:

Java异常架构与关键字

ssss在使用计算机语言进行项目开发的过程中,即使程序员把代码写得尽善尽美,在系统的运行过程中仍然会遇到一些问题,因为很多问题不是靠代码能够避免的,比如:客户输入数据的格式,读取文件是否存在,网络是否始终保持通畅等等。

ssss①:异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。Java异常是Java提供的一种识别及响应错误的一致性机制。Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。在有效使用异常的情况下,异常能清晰的回答what, where, why这3个问题:异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪”抛出,异常信息回答了“为什么”会抛出。

ssss②、Java程序在执行过程中所发生的异常事件可分为两类:

ssssss1、Throwable: Throwable 是 Java 语言中所有错误与异常的超类。Throwable 包含两个子类:Error(错误)和 Exception(异常),它们通常用于指示发生了异常情况。Throwable 包含了其线程创建时线程执行堆栈的快照,它提供了 printStackTrace() 等接口用于获取堆栈跟踪数据等信息。

ssssss2、Error(错误): 此类错误一般表示代码运行时Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。
ssss【注】:这些错误是不受检异常,非代码性错误。因此,当此类错误发生时,应用程序不应该去处理此类错误。按照Java惯例,我们是不应该实现任何新的Error子类的!

ssssss3、Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:空指针访问、试图读取不存在的文件、网络连接中断、数组角标越界。

sdsssssss异常分类:编译时异常和运行时异常

sdssdsssss3.1 运行时异常:是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序员应该积极避免其出现的异常。java.lang.RuntimeException 类及它的子类都是运行时异常。对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。

sdssdsssss3.2 编译时异常:是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。对于这类异常,如果程序不处理,可能会带来意想不到的结果。

ssss【注1】:对于这些错误,一般有两种解决方法:一是遇到错误就终止程序的运行。另一种方法是由程序员在编写程序时,就考虑到错误的检测、错误消息的提示,以及错误的处理。
ssss【注2】:ClassCaseException是运行时异常:
sdsdddddddss

异常处理机制


ssss在编写程序时,经常要在可能出现错误的地方加上检测的代码,如进行x/y运算时,要检测分母为0,数据为空,输入的不是数据而是字符等。过多的if-else分支会导致程序的代码加长、臃肿,可读性差。因此采用异常处理机制。

ssssJava采用的异常处理机制,是将异常处理的程序代码集中在一起,与正常的程序代码分开,使得程序简洁、优雅,并易于维护。
sssdsdsdsdsdsdsdss捕获异常:try-catch-finallyssss声明异常:throws + 异常类型

捕获异常:try-catch-finally

ssstry: 捕获异常的第一步是用try{…}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。

ssscatch(Exceptiontypee) :在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。

ssss【注】:捕获异常的有关信息:与其它对象一样,可以访问一个异常对象的成员变量或调用它的方法。getMessage(): 获取异常信息,返回字符串。printStackTrace(): 获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。

sssfinally :捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,catch语句是否执行,catch语句是否有异常,catch语句中是否有return,finally块中的语句都会被执行。finally语句和catch语句是任选的。

try-catch的使用规则:

dssss1.finally是可选的。

dssss2.使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象,根据此对象的类型,去catch中进行匹配。

dssss3.一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当前的try-catch结构(在没有写finally的情况)。继续执行其后的代码。

dssss4.catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错。

dssss 5.常用的异常对象处理的方式: ① String getMessage() ② printStackTrace()

dssss 6.在try结构中声明的变量,再出了try结构以后,就不能再被调用。

dssss7.try-catch-finally结构可以嵌套。

dssss体会1:使用try-catch-finally处理编译时异常,使得程序在编译时就不再报错,但是运行时仍可能报错,相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。

dssss体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了,针对于编译时异常,我们说一定要考虑异常的处理。

try-catch-finally中finally的使用:

dssss1.finally是可选的。 dssss2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有return语句等情况。 dssss 3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的 释放。此时的资源释放,就需要声明在finally中。

声明异常:throws

ssss声明抛出异常是Java中处理异常的第二种方式。如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

throws的使用规则:

dssss1. "throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常类型时,就会被抛出。异常代码后续的代码,就不再执行!关于异常对象的产生: ① 系统自动生成的异常对象 ② 手动生成一个异常对象,并抛出(throw)。

dssss2. try-catch-finally:真正的将异常给处理掉了。throws的方式只是将异常抛给了方法的调用者。 并没有真正将异常处理掉。

重写方法声明抛出异常的原则:

dssss①、子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型。

ds ss ②、开发中如何选择使用try-catch-finally 还是使用throws?

dsdsdssss如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果子类重写的方法中有异常,必须使用try-catch-finally方式处理。

dsdsdssss执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws 的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。

手动抛出异常:throw

ssssJava异常类对象除在程序执行过程中出现异常时由系统自动生成并抛出,也可根据需要使用人工创建并抛出。

dsssss首先要生成异常类对象,然后通过throw语句实现抛出 *** 作(提交给Java运行环境)。可以抛出的异常必须是Throwable或其子类的实例。

如何选择异常类型?

用户自定义异常类

ssss一般地,用户自定义异常类都是RuntimeException的子类。

ssss自定义异常类通常需要编写几个重载的构造器。

ssss自定义异常需要提供serialVersionUID

ssss自定义的异常通过throw抛出。

ssss自定义异常最重要的是异常类的名字,当异常出现时,可以根据名字判断异常类型。

package www.wwj.com.exceptiontest;

public class StudentTest {
    public static void main(String[] args) {
        try {
            Student s = new Student();
//		s.regist(1001);
            s.regist(-1001);
            System.out.println(s);
        } catch (Exception e) {
//			e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }
}
class Student{
    private int id;

    public void regist(int id) throws Exception{
        if(id > 0){
            this.id = id;
        }else{
//			System.out.println("您输入的数据非法!");
            //手动抛出异常
//			throw new RuntimeException("您输入的数据非法!");
            throw new MyException("不能输入负数");
        }
    }
    @Override
    public String toString() {  return "Student [id=" + id + "]"; }
}

class MyException extends RuntimeException{
    static final long serialVersionUID = -7034897193246939L;
    public MyException(){ }
    public MyException(String msg){ super(msg); }
}
异常总结:

Java异常常见面试题 Error 和 Exception 区别是什么?

ssssssError 类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,JAVA 应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;Exception 类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行。

运行时异常和一般异常(受检异常)区别是什么?

ssssss运行时异常包括 RuntimeException 类及其子类,表示 JVM 在运行期间可能出现的异常。 Java 编译器不会检查运行时异常。受检异常是Exception 中除 RuntimeException 及其子类之外的异常。 Java 编译器会检查受检异常。
ssssssRuntimeException异常和受检异常之间的区别:是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检异常,否则就选择非受检异常(RuntimeException)。一般来讲,如果没有特殊的要求,我们建议使用RuntimeException异常。

JVM 是如何处理异常的?

ssssss在一个方法中如果发生异常,这个方法会创建一个异常对象,并转交给 JVM,该异常对象包含异常名称,异常描述以及异常发生时应用程序的状态。创建异常对象并转交给 JVM 的过程称为抛出异常。可能有一系列的方法调用,最终才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈。
ssssssJVM 会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。当 JVM 发现可以处理异常的代码时,会把发生的异常传递给它。如果 JVM 没有找到可以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的一部分),默认异常处理器打印出异常信息并终止应用程序。

throw 和 throws 的区别是什么?

ssssssJava 中的异常处理除了包括捕获异常和处理异常之外,还包括声明异常和拋出异常,可以通过 throws 关键字在方法上声明该方法要拋出的异常,或者在方法内部通过 throw 拋出异常对象。

ssssssthrows 关键字和 throw 关键字在使用上的几点区别如下:

ssssssssthrow 关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出。
ssssssssthrows 关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表。一个方法用 throws 标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用 throws 关键字声明相应的异常。

final、finally、finalize 有什么区别?

ssssssfinal可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
ssssssfinally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
ssssssfinalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,Java 中允许使用 finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。

NoClassDefFoundError 和 ClassNotFoundException 区别?

ssssssNoClassDefFoundError 是一个 Error 类型的异常,是由 JVM 引起的,不应该尝试捕获这个异常。引起该异常的原因是 JVM 或 ClassLoader 尝试加载某类时在内存中找不到该类的定义,该动作发生在运行期间,即编译时该类存在,但是在运行时却找不到了,可能是变异后被删除了等原因导致;

ssssssClassNotFoundException 是一个受查异常,需要显式地使用 try-catch 对其进行捕获和处理,或在方法签名中用 throws 关键字进行声明。当使用 Class.forName, ClassLoader.loadClass 或 ClassLoader.findSystemClass 动态加载类到内存的时候,通过传入的类路径参数没有找到该类,就会抛出该异常;另一种抛出该异常的可能原因是某个类已经由一个类加载器加载至内存中,另一个加载器又尝试去加载它。

try-catch-finally 中哪个部分可以省略?

ssssss一般finally可以省略。

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

ssssss会执行,在 return 前执行。

ssss【注】:在 finally 中改变返回值的做法是不好的,因为如果存在 finally 代码块,try中的 return 语句不会立马返回调用者,而是记录下返回值待 finally 代码块执行完毕之后再向调用者返回其值,然后如果在 finally 中修改了返回值,就会返回修改后的值。显然,在 finally 中返回或者修改返回值会对程序造成很大的困扰,C#中直接用编译错误的方式来阻止程序员干这种龌龊的事情,Java 中也可以通过提升编译器的语法检查级别来产生警告或错误。例子如下。
sssdsdsdsdsddsdsddddsdsddsss
sssdsdsdsdsdsdssdsdsdsdsdssss
ssssss为什么会有这两种不同的结果呢?我们可以通过看其字节码来分析,对于图①:

类 ExampleA 继承 Exception,类 ExampleB 继承ExampleA,那如下代码会输出啥?
try {
	throw new ExampleB("b")
} catch(ExampleA e){
	System.out.println("ExampleA");
} catch(Exception e){
	System.out.println("Exception");
}

ssssss输出:ExampleA。

《Java 编程思想》示例输出什么?
class Annoyance extends Exception {
}
class Sneeze extends Annoyance {
}
class Human {
	public static void main(String[] args)
	throws Exception {
		try {
			try {
				throw new Sneeze();
			} catch ( Annoyance a ) {
				System.out.println("Caught Annoyance");
				throw a;
			}
		} catch ( Sneeze s ) {
			System.out.println("Caught Sneeze");
			return ;
		} finally {
			System.out.println("Hello World!");
		}
	}
}
结果:
Caught Annoyance
Caught Sneeze
Hello World!
常见的 RuntimeException 有哪些?

ssssssClassCastException(类转换异常)ssssssIndexOutOfBoundsException(数组越界)ssssssNullPointerException(空指针)ssssssArrayStoreException(数据存储异常, *** 作数组时类型不一致)ssssss还有IO *** 作的BufferOverflowException异常.

JAVA异常处理的实践技巧: 在 finally 块中清理资源或者使用 try-with-resource 语句

ssssss当使用类似InputStream这种需要使用后关闭的资源时,一个常见的错误就是在try块的最后关闭资源。问题就是,只有没有异常抛出的时候,这段代码才可以正常工作。try 代码块内代码会正常执行,并且资源可以正常关闭。但是,使用 try 代码块是有原因的,一般调用一个或多个可能抛出异常的方法,而且,你自己也可能会抛出一个异常,这意味着代码可能不会执行到 try 代码块的最后部分。结果就是,你并没有关闭资源。所以,你应该把清理工作的代码放到 finally 里去,或者使用 try-with-resource 特性。

public void doNotCloseResourceInTry() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);
        // use the inputStream to read a file
        // do NOT do this
        inputStream.close();
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

ssssss改进 1: 与前面几行 try 代码块不同,finally 代码块总是会被执行。不管 try 代码块成功执行之后还是你在 catch 代码块中处理完异常后都会执行。因此,你可以确保你清理了所有打开的资源。(finally中资源关闭也要用try-catch配合使用)。

public void closeResourceInFinally() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error(e);
            }
        }
    }
}

ssssss改进 2: Java 7 的 try-with-resource 语法如果你的资源实现了 AutoCloseable 接口,你可以使用这个语法。大多数的 Java 标准资源都继承了这个接口。当你在 try 子句中打开资源,资源会在 try 代码块执行后或异常处理后自动关闭。

public void automaticallyCloseResource() {
    File file = new File("./tmp.txt");
    try (FileInputStream inputStream = new FileInputStream(file);) {
        // use the inputStream to read a file
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}
优先明确的异常

ssssss你抛出的异常越明确越好,永远记住,你的同事或者几个月之后的你,将会调用你的方法并且处理异常。因此需要保证提供给他们尽可能多的信息。这样你的 API 更容易被理解。你的方法的调用者能够更好的处理异常并且避免额外的检查。因此,总是尝试寻找最适合你的异常事件的类,例如,抛出一个 NumberFormatException 来替换一个 IllegalArgumentException 。避免抛出一个不明确的异常。

public void doNotDoThis() throws Exception {
    ...
}
public void doThis() throws NumberFormatException {
    ...
}
对异常进行文档说明

ssssss当在方法上声明抛出异常时,也需要进行文档说明。目的是为了给调用者提供尽可能多的信息,从而可以更好地避免或处理异常。在 Javadoc 添加 @throws 声明,并且描述抛出异常的场景。

public void doSomething(String input) throws MyBusinessException {...}
使用描述性消息抛出异常、优先捕获最具体的异常

ssssss在抛出异常时,需要尽可能精确地描述问题和相关信息,这样无论是打印到日志中还是在监控工具中,都能够更容易被人阅读,从而可以更好地定位具体错误信息、错误的严重程度等。但这里并不是说要对错误信息长篇大论,因为本来 Exception 的类名就能够反映错误的原因,因此只需要用一到两句话描述即可。如果抛出一个特定的异常,它的类名很可能已经描述了这种错误。所以,你不需要提供很多额外的信息。一个很好的例子是 NumberFormatException 。当你以错误的格式提供 String 时,它将被 java.lang.Long 类的构造函数抛出。

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
}
public void catchMostSpecificExceptionFirst() {
    try {
        doSomething("A message");
    } catch (NumberFormatException e) {
        log.error(e);
    } catch (IllegalArgumentException e) {
        log.error(e)
    }
}
不要捕获 Throwable 类

ssssssThrowable 是所有异常和错误的超类。如果在 catch 子句中使用 Throwable ,它不仅会捕获所有异常,也将捕获所有的错误。JVM 抛出错误,指出不应该由应用程序处理的严重问题。 典型的例子是 OutOfMemoryError 或者 StackOverflowErr or 。两者都是由应用程序控制之外的情况引起的,无法处理。

public void doNotCatchThrowable() {
    try {
        // do something
    } catch (Throwable t) {
        // don't do this!
    }
}
不要忽略异常

ssssss很多时候,开发者很有自信不会抛出异常,因此写了一个catch块,但是没有做任何处理或者记录日志。但现实是经常会出现无法预料的异常,或者无法确定这里的代码未来是不是会改动(删除了阻止异常抛出的代码),而此时由于异常被捕获,使得无法拿到足够的错误信息来定位问题。合理的做法是至少要记录异常的信息。

public void logAnException() {
    try {
        // do something
    } catch (NumberFormatException e) {
        log.error("This should never happen: " + e); //不能什么都不写
    }
}
不要记录并抛出异常(最常被忽略的最佳实践)

ssssss很多代码甚至类库中都会有捕获异常、记录日志并再次抛出的逻辑,如下:

try {
    new Long("xyz");
} catch (NumberFormatException e) {
    log.error(e);
    throw e;
}

ssssss这个处理逻辑看着是合理的。但这经常会给同一个异常输出多条日志。如下:

17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"
Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.(Long.java:965)
at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)

ssssss如上所示,后面的日志也没有附加更有用的信息。如果想要提供更加有用的信息,那么可以将异常包装为自定义异常。

public void wrapException(String input) throws MyBusinessException {
    try {
        // do something
    } catch (NumberFormatException e) {
        throw new MyBusinessException("A message that describes the error.", e);
    }
}

ssssss因此,仅仅当想要处理异常时才去捕获,否则只需要在方法签名中声明让调用者去处理。

包装异常时不要抛弃原始的异常

ssssss捕获标准异常并包装为自定义异常是一个很常见的做法。这样可以添加更为具体的异常信息并能够做针对的异常处理。在你这样做时,请确保将原始异常设置为原因(注:参考下方代码 NumberFormatException e 中的原始异常 e )。Exception 类提供了特殊的构造函数方法,它接受一个 Throwable 作为参数。否则,你将会丢失堆栈跟踪和原始异常的消息,这将会使分析导致异常的异常事件变得困难。

public void wrapException(String input) throws MyBusinessException {
    try {
        // do something
    } catch (NumberFormatException e) {
        throw new MyBusinessException("A message that describes the error.", e);
    }
}
不要使用异常控制程序的流程

ssssss不应该使用异常控制应用的执行流程,例如,本应该使用if语句进行条件判断的情况下,你却使用异常处理,这是非常不好的习惯,会严重影响应用的性能。

使用标准异常

ssssss如果使用内建的异常可以解决问题,就不要定义自己的异常。Java API 提供了上百种针对不同情况的异常类型,在开发中首先尽可能使用 Java API 提供的异常,如果标准的异常不能满足你的要求,这时候创建自己的定制异常。尽可能得使用标准异常有利于新加入的开发者看懂项目代码。

异常会影响性能

ssssss异常处理的性能成本非常高,每个 Java 程序员在开发时都应牢记这句话。创建一个异常非常慢,抛出一个异常又会消耗1~5ms,当一个异常在应用的多个层级之间传递时,会拖累整个应用的性能。仅在异常情况下使用异常;在可恢复的异常情况下使用异常;尽管使用异常有利于 Java 开发,但是在应用中最好不要捕获太多的调用栈,因为在很多情况下都不需要打印调用栈就知道哪里出错了。因此,异常消息应该提供恰到好处的信息。

参考:

ssss九:异常(宋红康老师视频内容)ssssJava异常面试题(2020最新版)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5681722.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存