如上图所示,java中的Error和Exception都继承自Throwable
类,可以统称为“异常”,只是所表示的异常种类不同。
Error和Exception的区别
Error
类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。如java.lang.StackOverFlowError
和Java.lang.OutOfMemoryError
。对于这类错误,Java编译器不去检查他们。对于这类错误的导致的应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议让程序终止。Exception
类表示程序可以处理的异常,可以捕获且可能恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
Exception的分类
Exception 异常又可以分为 受检查异常 和 非检查异常, Java中所有继承自 RuntimeException
的异常都是非检查异常。
- 非检查异常
RuntimeException
:对于此类异常,java编译器不会去检查,从其名称也能窥探出此类异常会在程序运行时暴露出来。当出现此类异常时一般是程序人员的错误导致,比如数组越界、访问空指针等。 - 受检查异常:这类异常如果没有处理则在编译期就会被检查出来(如果使用IDE一般编辑代码时就会提示出来)。出现此类异常一般是由于外部因素导致的,比如尝试读取一个不存在的文件等.
异常相关问题(转载自 https://blog.csdn.net/zhengchao1991/article/details/52914234)
在Java异常处理的过程中,你遵循的那些最好的实践是什么?
这个问题在面试技术经理是非常常见的一个问题。因为异常处理在项目设计中是非常关键的,所以精通异常处理是十分必要的。异常处理有很多最佳实践,下面列举集中,它们提高你代码的健壮性和灵活性:
- 调用方法的时候返回布尔值来代替返回null,这样可以 NullPointerException。
catch块里别不写代码。空catch块是异常处理里的错误事件,因为它只是捕获了异常,却没有任何处理或者提示。通常你起码要打印出异常信息,当然你最好根据需求对异常信息进行处理。
能抛受控异常(checked Exception)就尽量不抛受非控异常(checked Exception)。通过去掉重复的异常处理代码,可以提高代码的可读性。
绝对不要让你的数据库相关异常显示到客户端。由于绝大多数数据库和
SQLException
异常都是受控异常,在Java中,你应该在DAO层把异常信息处理,然后返回处理过的能让用户看懂并根据异常提示信息改正操作的异常信息。在Java中,一定要在数据库连接,数据库查询,流处理后,在
finally
块中调用close()
方法。
既然我们可以用RuntimeException来处理错误,那么你认为为什么Java中还存在检查型异常?
- 其中一个理由是,存在检查型异常是一个设计上的决定,受到了诸如C++等比Java更早的编程语言设计经验的影响。绝大多数检查型异常位于java.io包内,这是合乎情理 的,因为在你请求了不存在的系统资源的时候,一段强壮的程序必须能够优雅的处理这种情况。通过把
IOException
声明为检查型异常,Java 确保了你能够优雅的对异常进行处理。 - 另一个可能的理由是,可以使用
catch
或finally
来确保数量受限的系统资源(比如文件描述符)在你使用后尽早 得到释放。
throw 和 throws这两个关键字在java中有什么不同?
一个java初学者应该掌握的面试问题。 throw
和 throws
乍看起来是很相似的尤其是在你还是一个java初学者的时候。尽管他们看起来相似,都是在处理异常时候使用到的。但在代码里的使用方法和用到的地方是不同的。
throws
总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常, 你也可以申明未检查的异常,但这不是编译器强制的。如果方法抛出了异常那么调用这个方法的时候就需要将这个异常处理。throw
是用来抛出任意异常的,按照语法你可以抛出任意Throwable
(i.e. Throwable 或任何Throwable的衍生类) ,throw
可以中断程序运行,因此可以用来代替return
. 最常见的例子是用 throw 在一个空方法中需要return的地方抛出UnSupportedOperationException
代码如下 :
private static void show() {
throw new UnsupportedOperationException("Not yet implemented");
}
Java中final, finalize, finally关键字的区别
final
和 finally
是Java的关键字,而 finalize()
则是方法。
final
关键字在创建不可变的类的时候非常有用,只是声明这个类是final
的。finalize()
方法则是垃圾回收器在回收一个对象前调用,但也 Java规范里面没有保证这个方法一定会被调用。finally
关键字是唯一一个和异常处理相关的关键字。在你的产品代码中,在关闭连接 和资源文件的是时候都必须要用到finally
块。finally
代码块中的语句无论怎样都会执行,并且在return之前执行。也就是说,如果在try
或catch
中有return
语句,那么在return之前会先执行finally
的代码,但是,finally
的代码不会改变return
的值 。例:
public class FinallyTest {
static int x = 1;
public static void main(String[] args) {
System.out.println(new FinallyTest().test()); //输出:2
System.out.println(this.x); //输出:3
}
static int test() {
try {
x++;
return x;
} finally {
++x;
}
}
}