每天几道Java面试题:异常机制(第三天)


友情提醒

背面试题很枯燥,加入一些戏剧场景故事人物来加深记忆。PS:点击文章目录可直接跳转到文章指定位置。

第三幕、

第一场)异常机制面试题

【面试官老吉,面试官潘安,面试者老王】

老吉:今天有60场面试,从早上九点,到晚上六点。我们快点开始吧。1.Error、Exception区别

老王:你姓王吗?
①Error类和Exception类的父类都是throwable类
②Error类一般是指与虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢等。仅靠程序本身无法恢复和和预防,建议让程序终止。
③Exception类表示程序可以处理的异常,可以捕获且可能恢复。应该尽可能处理,而不应该随意终止异常。

王老吉:反正我不姓加。下一个问题你问吧,潘安。

潘安:程序出了问题还可以抛出异常,国家出了问题又能怎么办呢。西晋惠帝时期的八王之乱导致了五胡乱华,而我也在八王之乱中被杀了。所以:2.说一下Java中的异常处理机制的简单原理和应用。

老王:才三十二岁,你就有白头发了,Java程序员这一行不好干啊。
①异常是指java程序运行时(非编译)所发生的非正常情况或错误。异常处理机制是识别及响应错误的机制。
②Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象中,该对象中包含有异常的信息,我们也可以自定义异常类(继承Exception或RuntimeException)。所有异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error(一般不关注)和Exception(合理的应该处理的异常)。
③异常分为运行时异常和编译期异常
编译器强制编译期异常必须try…catch处理或用throws声明继续抛给上层调用方法处理,所以编译期异常也称为checked异常。
④而运行异常可以用try catch抓取也可以不处理,所以编译器不强制用try…catch处理或用throws声明。

潘安:3.常见的异常

老王:ArithmeticException(算术异常)
ClassCastException (类转换异常)
IllegalArgumentException (非法参数异常)
IndexOutOfBoundsException (下标越界异常)
NullPointerException (空指针异常)

老吉:4.说一下异常处理:throw,throws和try…catch…finally

老王:如果异常一直用throw抛出总不是个事情,异常总得有处理的时候这时候需要用到throws和try…catch…finally

/*格式: try{
            //可能出现异常的代码
        }catch(异常类型1 对象名){
            //逻辑代码
        }catch(异常类型2 对象名){
            //逻辑代码
        }
 */
public class TestException_3 {
    
    
    public static void main(String[] args) {
    
    
        test2();
    }

 public static void test2() {
    
    
        /*
            运行时异常:数组下标越界异常
                java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10
         */
        try {
    
    
            int[] arr = new int[10];
            System.out.println(arr[10]);
        } catch (Exception e) {
    
         //参数位置可能发生多态        万能捕获器       表现:Exception e = new ArrayIndexOutOfBoundsException();
            e.printStackTrace();    //打印堆栈信息 ==> 将异常对象所属的类型、原因、涉及的行数打印展示在控制台
//            System.out.println(e.getMessage());       //得到异常出现的原因
        }

        System.out.println("执行了");
    }
}


try…catch…finally结构中,finlly被定义在最后位置,将一定需要被执行的代码定义在finally的内部,finally中的代码一定会被执行。

/*格式: try{
            //可能出现异常的代码
        }catch(异常类型1 对象名){
            //逻辑代码
        }catch(异常类型2 对象名){
            //逻辑代码
        }finally{
            //定义一定需要被执行的代码
        }
 */
public class TestException_3 {
    
    
    public static void main(String[] args) {
    
    
        test4();
    }
 public static void test4() {
    
    
        FileInputStream fis = null;
        try {
    
    
            fis = new FileInputStream("hello2.txt");
            int len;
            while ((len = fis.read()) != -1) {
    
    
                System.out.println((char) len);
            }
            int num = 10 / 0;
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }finally {
    
    	//这里面的代码一定会执行
            try {
    
    
                if (fis != null) {
    
    
                    fis.close(); 
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        System.out.println("执行了");
    }
}

异常声明处理:throws(延后处理):一个方法产生了一个它不想立即处理的异常时,那么就需要在该方法的头部使用throws主动声明这个异常,告诉调用者可能出现问题,后面交给外部进行处理,以达到延后处理的目的。如下:m1方法中的异常最终交给了m3方法解决。

/* 关键字:throws	格式:
        public ... 返回值类型 方法名(形参列表) throws 异常类型1,异常类型2,...,异常类型n{
            //方法体
        }
 */
public class TestException_4 {
    
    
    public static void main(String[] args) {
    
    
        m3();
    }

    public static void m3(){
    
    
        try {
    
    
            m2();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

    public static void m2() throws IOException {
    
    
        m1();
    }

    public static void m1() throws IOException {
    
    
        FileInputStream fis = new FileInputStream("hello.txt");
        int len;
        while ((len = fis.read()) != -1) {
    
    
            System.out.println((char) len);
        }
        fis.close();
    }
}


throw 关键字用来在程序中明确的抛出异常,什么是抛出异常呢?为了明确指出此方法不捕获这类异常,并且要让调用该方法的其他方法去捕获处理该异常。我们就使用throws明确的抛出(产生)该类异常

/*
    演示手动抛出异常对象=关键字:throw
 */
public class TestException_5 {
    
    
    public static void main(String[] args) {
    
    
        People p = new People("张三", 140);
        System.out.println(p);
        //...
    }
}
//------------------------------分割----------------------------
class People{
    
    
    private String name;
    private int age;
    public People() {
    
     }
    public People(String name, int age) {
    
    
        this.name = name;
        //数据合理性的校验
        if (age <= 0 || age > 130) {
    
    
//      System.out.println("年龄不合理...");  //打印信息
//      throw new RuntimeException("年龄有误!"); //抛出异常,因为是运行时异常可以处理也可以不处理
//      throw new Exception("年龄有误..."); //抛出异常,因为不是运行时异常所以必须处理
   throw new MyException("年龄有误...");//抛出异常,因为是运行时异常的子类可以处理也可以不处理
        } else {
    
    
            this.age = age;
        }
    }
    public String getName() {
    
    return name;}
    public void setName(String name) {
    
    this.name = name;}
    public int getAge() {
    
    return age;}
    public void setAge(int age) {
    
    this.age = age;}
    @Override
    public String toString() {
    
    
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


潘安:5.final,finally,finalize区别

老王:
①final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。
②finally是异常处理语句结构的一部分,表示总是执行。
③finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的finalize方法, finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。例如关闭文件等。JVM不保证此方法总被调用

潘安:今天就面试到这吧,你没通过。去别的公司面试吧。

老王:为什么?

潘安:我们公司以貌取人。

猜你喜欢

转载自blog.csdn.net/baomingshu/article/details/132799535