一:Error 和 Exception 区别
Error 类型的错误通常为虚拟机相关错误
,如系统崩溃,内存不足,堆栈溢出 等,编译器不会对这类错误进行检测,JAVA 应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;
Exception 类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错 误,应对其进行处理,使应用程序可以继续正常运行。
二: JVM 是如何处理异常的
在一个方法中如果发生异常,这个方法会创建一个异常对象,并转交给 JVM, 创建异常对象并转交给 JVM 的过程称为抛出异常
。
该异常对象包含异常名称,异常描述以及异常发生时应用程序的状态
。
在抛出异常前,可能有一系列的方法调用,调用完才进入抛出异常的方法,这一系列方法调用的有序列表叫做调用栈。
JVM 会顺着调用栈去查找看是否有可以处理异常的代码,如果有,则调用异常处理代码。
当 JVM 发现可以处理异常的代码时,会把发生的异常传递给它。
如果JVM 没有找到可以处理该异常的代码块,JVM 就会将该异常转交给默认的异常处理器(默认处理器为 JVM 的一部分),默认异常处理器打印出异常信息并终止应用程序。
三:final、finally、finalize 有什么区别?
final可以修饰类、变量、方法,
修饰类表示该类不能被继承、修饰方法表示该方 法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
finally一般作用在try-catch代码块中,
在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用 来存放一些关闭资源的代码。
finalize是一个方法,属于Object类的一个方法,
而Object类是所有类的父类, Java 中允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
四: NoClassDefFoundError 和ClassNotFoundException 区别?
NoClassDefFoundError 是一个 Error 类型的异常,是由 JVM 引起的,不应该尝试捕获这个异常。
引起该异常的原因是 JVM 或 ClassLoader 尝试加载某类时在内存中找不到该类 的定义,该动作发生在运行期间,即
编译时该类存在,但是在运行时却找不到 了
,可能是编译后被删除了等原因导致;
ClassNotFoundException 是一个受查异常,需要显式地使用 try-catch 对其 进行捕获和处理,或在方法签名中用 throws 关键字进行声明。
当使用 Class.forName, ClassLoader.loadClass 或
ClassLoader.findSystemClass 动态加载类到内存的时候,通过传入的类路径参数没有找到该类,就会抛出该异常;
另一种抛出该异常的可能原因是某个类已经由一个类加载器加载至内存中, 另一个加载器又尝试去加载它。
五:try-catch-finally 中哪个部分可以省略?
catch 可以省略
原因:
-
try只适合处理运行时异常,
-
try+catch适合处理运行时 异常+普通异常。
也就是说,如果你只用try去处理普通异常却不加以catch处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必须用 catch显示声明以便进一步处理。而运行时异常在编译时没有如此规定,所以 catch可以省略,你加上catch编译器也觉得无可厚非。
- 理论上,编译器看任何代码都不顺眼,都觉得可能有潜在的问题,所以你即使对 所有代码加上try,代码在运行期时也只不过是在正常运行的基础上加一层皮。
- 但是你一旦对一段代码加上try,就等于显示地承诺编译器,对这段代码可能抛 出的异常进行捕获而非向上抛出处理。
- 如果是普通异常,编译器要求必须用 catch捕获以便进一步处理;
- 如果运行时异常,捕获然后丢弃并且+finally扫尾处理,或者加上catch捕获以便进一步处理。
-
加上finally,则是在不管有没捕获异常,都要进行的“扫尾”处理。
六:try-catch-finally 中,如果 catch 中 return 了, finally 还会执行吗?
会执行,在 return 前执行。
七:常见的 RuntimeException 有哪些?
ClassCastException(类转换异常)
IndexOutOfBoundsException(数组越界)
NullPointerException(空指针)
ArrayStoreException(数据存储异常,操作数组时类型不一致)
还有IO操作的BufferOverflowException异常
八: Java常见异常有哪些
java.lang.IllegalAccessError:违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常。
java.lang.InstantiationError:实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.
java.lang.OutOfMemoryError:内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。
java.lang.*Error:堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出或者陷入死循环时抛出该错误。
java.lang.ClassCastException:类造型异常。假设有类A和B(A不是B的父类或子类),O是A的实例,那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。
java.lang.ClassNotFoundException:找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。
java.lang.ArithmeticException:算术条件异常。譬如:整数除零等。
java.lang.ArrayIndexOutOfBoundsException:数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。
java.lang.IndexOutOfBoundsException:索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常。
java.lang.InstantiationException:实例化异常。当试图通过newInstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常。
java.lang.NoSuchFieldException:属性不存在异常。当访问某个类的不存在的属性时抛出该异常。
java.lang.NoSuchMethodException:方法不存在异常。当访问某个类的不存在的方法时抛出该异常。
java.lang.NullPointerException:空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。
java.lang.NumberFormatException:数字格式异常。当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常。
java.lang.StringIndexOutOfBoundsException:字符串索引越界异常。当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常
九:异常会影响性能
异常处理的性能成本非常高,每个 Java 程序员在开发时都应牢记这句话。**创建一个异常非常慢,抛出一个异常又会消耗1~5ms,**当一个异常在应用的多个层级之间传递时,会拖累整个应用的性能。