• java基础---异常处理


    =====什么是Throwable?Exception?error?Exception有哪两种?什么是检查型异常和非检查型异常呢?常见的非检查型异常有什么呢?他们之间有什么区别?

    Throwable是所有异常和错误的超类父类,包括了它的子类Error和Exception.
    Exception是异常,包括两种异常checkedException和UnCheckedException,区别在于他们的处理方式。检查型异常需要使用try, catch和finally关键字在编译期进行处理,否则会出现编译器会报错。对于非检查型异常则不需要这样做。
     
    Java中所有继承自java.lang.Exception类的异常都是检查型异常。
     
    所有继承自RuntimeException的异常都被称为非检查型异常。包括IllegalArgumentException、IllegalStateException、NullPointerException、IndexOutOfBoundsException。非检查型异常都是程序运行时候出现的异常,不需要进行捕获,因为虚拟机默认会printStackTrace()打印错误的堆栈信息。
     
    Error是错误,一般包括编译型错误或者系统的错误,如java.lang.StackOverFlowError 或者 Java.lang.OutOfMemoryError 之类的。
     
     
    ===常见的OOM内存溢出和常见stackOverFlow异常?
     
     
     
     
    ===常见的runtimeException非法输入,数组越界,空指针异常
    illegalArgument,illegalStateException
    nullPointerException,indexOutofbounds
     
     
    ===?为什么RuntimeException使用try catch是没有用的?
    因为往往代码运行初期没问题,但是运行到一定程度了就会出问题,而这种问题是代码本身没写好,你try...catch了,bug依然是存在的。
     
     
    ===如何处理空指针nullpointerexception异常问题,有什么最佳实践方式?
    数据库查询,远程调用和集合元素返回时要判断是否为空。
     
     
     
    ===?区分编译时异常和运行时异常?
    indexOutOf异常是runtimeException
    编译时异常:语法不对
    运行时异常:代码逻辑有错
    编译时异常一般指的是编译器对于语法规范的一些检查,如果不同过的话,现在的大部分编译器就会及时提示。不改正时无法进行编译的。而运行时异常(runtime exception),则不会影响程序的编译,而是在运行过程中调用某部分方法时,抛出异常。如下题,很多人会抓住刚学的知识点,忽略其他部分,正确答案应该是A。语句的书写时没有错误的,而在运行时会发生下标越界的错误。
     
     
     
     
     
    ===================================================================
    补充部分
     
     
     
    ===try--catch---finally的处理执行顺序
    1、不管有木有出现异常,finally块中代码都会执行;
    2、当try和catch中有return时,finally仍然会执行;
    3、finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;
    4、finally中最好不要包含return,否则程序会提前退出,返回值不是try或catch中保存的返回值。
    总结:finally一定会执行,try.catch中的return参数一定会先保存起来,等finally执行完之后再返回,如果finally直接返回return,那么就会丢失掉try.catch里面的参数。
     
     
    ===java异常的最佳实践
    1.像空指针,数组越界等等runtimeException尽量预先检查代码排除掉。空指针的可能出现位置:数据库查询,集合数据处理都要进行空判断。
    2.不能将大面积的代码直接包在try...catch里面,必须区分稳定代码和不稳定的代码。
    3.事务回滚在catch块中必须手动回滚
    4.finally块必须对资源对象,流对象进行关闭,也必须try-catch
     
     
    =====如何自定义异常,并且如何手动抛出异常?
    异常是一个类并实例化成对象,所以必须要用类去继承Exception创建自定义的异常类。
    public class MyException extends Exception{
         private int id;
         public MyException(String message,int id){
             super(message);//定义构造方法,继承父类
             this.id = id;
         }
         public int getId(){
             return id; 
         }
    }
    //创建测试类
    public class TestException{
         public void regist(int num) throws MyException{
             if( num < 0 ){//手动抛出异常
              throw new MyException(“人数为负值”,1);
              } 
         }
         public void manage(){
             try{
              regist(-100);//抛出的异常在调用它的方法中进行处理
         }catch(MyException e ){
              System.out.println(“人数不能够为负数");
               e.printStackTrace();   
         } 
         }
    }
     
     
     
    ===?为什么在catch块里面能够再抛出一个RuntimeException并且不需要catch处理,但是不能够抛出一个Exception呢?为什么在catch块里面抛出了一个RuntimeException之后就能够中断线程的执行呢?是不是只能够通过抛RuntimeException来中断线程呢?
    1.因为RuntimeException是不需要被catch的,而Exception包括RuntimeException和checkedException检查型异常,检查型异常是需要catch处理的。
    2.抛出RuntimeException的时候程序就会中断了!!并且如果你不去catch这个RuntimeException的时候程序就会中断,否则你catch了就会继续执行。
    3.不只能通过抛RuntimeException来中断进程,因为其他的异常必须try catch处理掉。也可以抛其他异常,然后break;来中断进程。
     
     
     
     
     
    ===?如何在遍历一个集合的时候删除掉某个元素或者添加元素?为什么要用迭代器来进行删除,而不用集合自带的add或者delete方法呢? 比如说add,remove之类的操作, 搞不好就会抛ConcurrentModificationException,为什么会抛出这个异常呢?
    因为有个参数modCount记录了集合被修改的次数,用集合自带的方法进行修改的时候,这个modCount直接就改变了。
    用迭代器进行迭代的时候,想删除某个元素,就会比较这个参数和另一个期望参数的值,如果相同就会删掉这个元素,否则就会抛出异常。因为使用迭代器进行迭代的时候是能够一直保证mo
     
    Iterator iterator = list.iterator();
    while(iterator.hasNext()){
         Object obj = iterator.next();
         iterator.delete();//必须使用这种删除方式否则报错
         //list.remove(..)这种方式删除必定报错,抛出ConcurrentModificaionException异常
    }
     
     
    ===?为什么会报出ConcurrentModificationException的异常?
    final void checkForComodification() {
            if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
        }
    抛出异常的判断是以上这句,迭代过程中会判断这两个参数
    源码是这么描述的:ArrayList 继承了 AbstractList, 其中AbstractList 中有个modCount 代表了集合修改的次数。在ArrayList的iterator方法中会判断 expectedModCount与 modCount是否相等,如果相等继续执行,不相等报错,只有iterator的remove方法会在调用自身的remove之后让 expectedModCount与modCount再相等,所以是安全的。
    【错误原因】 对于remove操作,list.remove(o)的时候,只将modCount++,而expectedModCount值未变,那么迭代器在取下一个元素的时候,发现该二值不等,则抛ConcurrentModificationException异常。 
    【解决办法】 
    • remove:用iterator提供的原生态remove() 
    • add:同remove就错了,iterator没有提供原生的add()方法。要用新的容器暂存,然后再遍历结束后,全部添加到原容器当中。 
    • set/list:这两类常用容器,就用上面说的方法remove(), add()就好了。 
    • map:直接使用ConcurrentHashMap就ok。为什么别的容器,不也实现个concurrent版本直接用。。?库里不搞,自己搞。 
  • 相关阅读:
    计蒜客 动态规划基础 蒜头跳木桩
    委托的使用和合并
    asp.net "callback" 和 "postback" 的区别.
    3 顶层父类
    2 异常类
    1 智能指针
    16 #error 和 #line
    15 条件编译
    14 宏
    13 编译和链接
  • 原文地址:https://www.cnblogs.com/buptyuhanwen/p/9396823.html
Copyright © 2020-2023  润新知