Java面试题汇总之异常

一、throw 和 throws 的区别?

原文链接:https://blog.csdn.net/hjfcgt123/article/details/53349275

抛出异常有三种形式,一是throw,一个throws,还有一种系统自动抛异常。下面它们之间的异同。

(1)系统自动抛异常

当程序语句出现一些逻辑错误、语义错误或类型转换错误时,系统会自动抛出异常:(举个栗子)

public static void main(String[] args) { 
    int a = 5, b =0; 
    System.out.println(a/b); 
    //function(); 
}

 此时系统会抛出ArithmeticException(算术异常)。

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at basis.ByZero.main(ByZero.java:7)

 或者:

public static void main(String[] args) { 
    String s = "abc"; 
    System.out.println(Double.parseDouble(s)); 
    //function(); 
}

系统会自动抛出NumberFormatException(数据格式异常)。

Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"

 (2)throw

throw是语句抛出一个异常,一般是在代码块的内部,当程序出现某种逻辑错误时由程序员主动抛出某种特定类型的异常。

public static void main(String[] args) { 
    String s = "abc"; 
    if(s.equals("abc")) { 
      throw new NumberFormatException(); 
    } else { 
      System.out.println(s); 
    } 
    //function(); 
}

 运行时,系统会抛出NumberFormatException(数据格式异常):

Exception in thread "main" java.lang.NumberFormatException: For input string: "abc"

(3)throws

throws是方法可能抛出异常的声明。(用在声明方法时,表示该方法可能要抛出异常。

public void function() throws Exception{......}

 

public class testThrows {
 
    public static void function() throws NumberFormatException {
        String s = "abc";
        System.out.println(Double.parseDouble(s));
    }
 
    public static void main(String[] args) {
        try {
            function();
        } catch (NumberFormatException e) {
            System.err.println("非数据类型不能强制类型转换。");
            //e.printStackTrace(); 
        }
    }
}
 

运行时控制台输出:

非数据类型不能强制类型转换。

(4)throw与throws的比较

  • throws出现在方法函数头;而throw出现在函数体。
  • throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。
  • 两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。

(5)编程习惯

在写程序时,对可能会出现异常的部分通常要用try{...}catch{...}去捕捉它并对它进行处理;用try{...}catch{...}捕捉了异常之后一定要对在catch{...}中对其进行处理,那怕是最简单的一句输出语句,或栈输入e.printStackTrace();

如果是捕捉IO输入输出流中的异常,一定要在try{...}catch{...}后加finally{...}把输入输出流关闭;

如果在函数体内用throw抛出了某种异常,最好要在函数名中加throws抛异常声明,然后交给调用它的上层函数进行处理。

二、final、finally、finalize 有什么区别?

原文链接:https://www.cnblogs.com/ktao/p/8586966.html

(1)final

final是用来修饰类、方法、变量的关键字,被 final 修饰的类不能被继承,final类中的所有成员方法都会被隐式的定义为 final 方法。

final 修饰的方法不能被重写;

final 修饰的基本数据类型的变量是常量,定义时必须初始化,不能再次被赋值;final 修饰引用类型的数据(String 除外)时,其引用不可被修改,但是引用的对象中的数据可以被修改。

(2)finally

finally作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。(×)(这句话其实存在一定的问题)。

(3)finallize

finalize()是在java.lang.Object里定义的,也就是说每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。 
特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。 
  使用finalize还需要注意一个事,调用super.finalize();

  一个对象的finalize()方法只会被调用一次,而且finalize()被调用不意味着gc会立即回收该对象,所以有可能调用finalize()后,该对象又不需要被回收了,然后到了真正要被回收的时候,因为前面调用过一次,所以不会调用finalize(),产生问题。 所以,推荐不要使用finalize()方法,它跟析构函数不一样。

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

catch 和 finally 语句块可以省略其中一个。

try-finally语句块,不能捕获异常,只能释放资源,通常用在业务分层程序中的底层模块。

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

会。try、catch、finally里面均允许存在return语句,但是,在 finally 中不建议使用 return 语句,有可能导致程序无法正常返回。在try或 catch 中执行 return 语句不影响 finally 中语句的执行。当 try 或 catch 中的 return 语句将要返回时,程序会检测发现存在 finally 语句,此时程序会跳进 finally 语句块中执行,执行完 finally 中的语句后,然后再返回到原来将要执行的 return 语句,方法返回,程序结束。

(1)try和catch中均有return(finally中不包含return):

package basis.exception;

public class ByZero {
    public static void main(String[] args) {
        System.out.println(testReturn());
    }
    public static String testReturn(){
        try{
            System.out.println(3/0);
            return "try";
        }catch (Exception e){
            e.printStackTrace();
            return "catch";
        } finally {
            System.out.println("资源释放。");
        }
    }
}

当 try 和 catch 中均包含 return 语句时(finally不包含return语句),如果 try 中代码不发生异常,此时,方法在 try 语句中的 return 返回并结束(当然,返回前会先执行完 finally 中的语句);如果 try 中的代码发生了异常,那么程序在执行完 finally 中的语句后,从 catch 语句块中的 return 语句返回并结束。

(2)try和catch、finally中均包含return:

package basis.exception;

public class ByZero {
    public static void main(String[] args) {
        System.out.println(testReturn());
    }
    public static String testReturn(){
        try{
            System.out.println(3/1);
            return "try";
        }catch (Exception e){
            e.printStackTrace();
            return "catch";
        } finally {
            System.out.println("资源释放。");
            return "finally";
        }
    }
}

如果 try 和 catch、finally中均包含return 语句,我们依旧分情况 讨论,不发生异常时,程序执行到 try 中的 return 语句时会转去执行 finally 中的语句,并在 finally 返回并结束;发生异常时,程序执行到 catch 中的 return 语句时会转去执行 finally 中的语句,并在 finally 返回并结束。

所以,finally 中的 return 语句会屏蔽掉其他return 语句,容易导致程序不能正常放回并结束。

(3)面试题:异常返回和i++

package basis.exception;

public class ByZero {
    public static void main(String[] args) {
        System.out.println(testReturn());
    }
    public static int testReturn(){
        int i = 10;
        try{
            return i++;
        }catch (Exception e){
            return i++;
        } finally {
            i++;
            System.out.println("资源释放。i="+i);
        }
    }
}

 先说运行结果:方法 testReturn 返回 10,finally 语句中输出 i = 12。为什么呢?

程序运行到 try 中的 return 语句时,此时(i++)的值为 10 ,程序在将要返回 10 时,发现存在 finally 语句块,于是,先把结果 10 保存在临时变量中,转而去执行 finally 语句,finally 语句执行完后输出 i 的值为 12 。待 finally 语句执行完成后,再回到 try 中,然后返回 保存在临时变量中的 10 并结束。

5、常见的异常类有哪些?

原文链接:https://blog.csdn.net/meism5/article/details/90414205

常见的异常类有哪些?
异常非常多,Throwable 是异常的根类。

Throwable 包含子类 错误-Error 和 异常-Exception 。

Exception 又分为 一般异常和运行时异常 RuntimeException。

运行时异常不需要代码显式捕获处理。

下图是常见异常类及其父子关系:
Throwable
|  ├ Error  

|  │ ├ IOError

|  │ ├ LinkageError

|  │ ├ ReflectionError

|  │ ├ ThreadDeath

|  │ └ VirtualMachineError

|  │ 

|  ├ Exception  

|  │ ├ CloneNotSupportedException

|  │ ├ DataFormatException

|  │ ├ InterruptedException

|  │ ├ IOException

|  │ ├ ReflectiveOperationException

|  │ ├ RuntimeException 

|  │    ├ ArithmeticException

|  │    ├ ClassCastException

|  │    ├ ConcurrentModificationException

|  │    ├ IllegalArgumentException

|  │    ├ IndexOutOfBoundsException

|  │    ├ NoSuchElementException

|  │    ├ NullPointerException

|  │   └ SecurityException

|  │   └  SQLException
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值