`
new_Line
  • 浏览: 9778 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_java异常

 
阅读更多

------- android培训java培训、期待与您交流! ----------

异常:
    异常的体系:
    Throwable:
        Error:(大问题)通常出现重大问题如:运行的类不存在
               或者内存溢出等。不编写针对代码对其处理
        Exception:(小问题)运行时出错
           Exception():无参构造器
           Exception(String msg):带有消息文本的构造器
           Exception(Throwable cause):带有起因的构造器
           Exception(String msg, Throwable cause):有消息文本,也有起因的构造器。
    异常体系的特点:
    异常体系中的所有类,以及建立的对象都具备可抛性,也即是说可以被throw和throws关键字
    操作,也只有异常体系具备这个特点
    异常处理机制:
    Java的异常处理机制可以让程序具有极好的容错性,让程序更加健壮。当程序运行出现意外情况时,
    系统会自动生成一个Exception对象来通知程序,从而实现将"业务功能实现代码"和"错误处理代码"
    分离,提供更好的可读性。
   
    异常类方法介绍:
      String getMessage(),获取异常信息,返回字符串
     String toString(),获取异常类名和异常信息,返回字符串。
      void printStackTrace(),获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
    异常的分类:
    1:编译时异常
           该异常在编译时期,如果没有处理,编译失败。该异常被标识,代表可以被处理
    2:运行时异常
        在编译时不需要处理,编译器不检查。该异常的发生,建议不处理,让程序停止,需要对代码进行修正
    异常的处理:
    1:使用throws声明异常:
        当方法不知道如何处理这种类型的异常,该异常应该由上一级调用者处理;如果main方法也不知道
        如何处理这种异常,也可以使用throws声明抛出异常,该异常将交给JVM处理。JVM对异常的处理方
        法是:打印异常跟踪栈信息,并终止程序。throws可以声明多个异常类,多个异常类之间以逗号隔
        开。throws声明抛出的语法如下:
             [修饰符] [返回值类型] [方法名] throws XXException, XXXException...{}
             代码示例:
            public class ThrowsTest{
                public static void main(String[] args) throws IOException
                {
                    FileInputStream fis = new FileInputStream("b.java");
                }
            }
             上面程序使用了throws声明抛出IOException异常,一旦使用throws声明抛出异常,程序无需使用
             try...catch来捕获异常。
        使用throw抛出异常:
        如果程序中的数据、执行与既定的业务需求不符而产生的异常,必须由程序员来决定抛出,系统无法
        抛出这种异常。则应该使用throw语句,throw语句可以单独使用,它抛出的不是异常类,而是异常类
        的实例,而且每次只能抛一个异常实例。格式如下:
            throw new 异常类("描述信息");
             代码示例:
            /*
                需求:求两个数的和,当一个数小于等于0的时候,抛出异常
             */
             public class Deom{
                public static void main(String[] args)
                {
                    int sum = sum(-2, 3);
                    System.out.println(sum);
                }
                public static int sum(int a, int b)
                {
                    if(a <= 0 || b <= 0)
                        throw new RuntimeException("出现负数");
                    return a + b;
                }
             }
        throw和throws的区别:
        |--throws:
            声明,使用在函数()和{}之间,后面跟着异常类,可以有多个,逗号隔开
        |--throw:
            抛出,使用在函数内,后面跟着异常类对象
    2:使用try...catch捕获异常
            格式一:
          try {
            //需要被检查的代码
            } catch()
            {
            //处理异常的代码(处理方式)
            }
        try块是监控区,在try中出现的异常会被捕获,然后送到catch之后,与catch所处理的异常类型进行比较,
        如果匹配,那么就把异常对象交给catch了,然后调用catch块。注意,在try块中,出现了异常后,
        在出现异常的位置直接跳转到catch中,而try后面的语句就不会在执行了。

        格式二:
            try{
              //需要被检查的代码
            }finally
            {
            //一定会执行的语句
            }
       

        格式三:
            try
            {
                //需要被检查的代码
            }catch(异常类 变量名)

            {
                //处理异常的代码(处理方式)
            }finally
            {
                //一定会执行的语句
            }
        如果try中没有抛出异常,那么不会执行catch,但无论有无异常都会执行finally
          如果try有异常,那么会执行catch,但有异常,也会执行finally
        如果在finally之前有返回语句(return和抛出异常语句),那么会在返回之前先执行finally,然后再继续返回
    |--示例代码:
         public class Test7 {
        public static void main(String[] args) {
            int x  = fun();
            System.out.println("最終x的值是,x = " + x); //打印的值是6
        }
        @SuppressWarnings("finally")
        public static int fun(){
            int x = 0;
            try{
                //
                x = 6;
                return x;
            }finally{
                x = 10;
                //将x的值输出,测试return是在finally执行后才返回
                System.out.println("finally中的x執行了,x = " + x);//打印的值是10
            }
        }
         }
        finally中放什么样的代码
        通常我们会用来断开外部资源绑定。例如我们的程序绑定了一个磁盘上的文件,
        如果在方法返回之前,可以断开,那么就应该把断开的语句放到finally中,
        这样可以保证断开的语句总是执行。
        finally中不会执行的情况
            finally遇见了System.exit(0)时,就不会再执行了。因为System.exit(0)会把JVM停止了。
        使用try...catch处理异常注意事项:
           在方法内部把异常处理掉,外界不知道内部的问题,也不会让调用者出现异常。
           注意:当声明多个异常,就对应要有几个catch块,父类的catch块要放到最后,catch内
           需要定义针对性的处理方式,不要简单定义printStackTrace。当捕获的异常,本功能处理
           不了时,可以继续在catch中抛出,如果该异常处理不了,但并不属于该功能出现的异常,
           可以将异常转换后抛出
        代码示例:
        public class Teacher {
            private String name;
            private Computer cmpt;
            public Teacher(){}
            public Teacher(String name)
            {
                this.name = name;
                cmpt = new Computer();
            }
            public void prelect() throws TeacherException
            {
                try {
                    cmpt.run();
                } catch (LanPinException e) {
                    cmpt.reset();
                } catch (MaoYanException e) {
                    practice();
                    //将异常转换抛出
                    throw new TeacherException("课时计划无法完成" + e.getMessage());
                    //System.out.println("");throw单独存在的时候,后面不能有语句
                }
                System.out.println("开始上课了");
            }
            public void practice()
            {
                System.out.println("做练习");
            }
        }
        public class Computer {
            private int state = 3;
            public void run() throws LanPinException, MaoYanException
            {
                /*
                   通过改变状态值,来测试效果
                 */
                if(state == 2)
                    throw new LanPinException("蓝屏了");
               
                if(state == 3)
                    throw new MaoYanException("冒烟了");
                System.out.println("电脑运行了");
            }
            public void reset()
            {
                state = 1;
                System.out.println("电脑重启");
               
            }
        }
        /*
            自定义异常类
         */
        public class LanPinException extends Exception {
            public LanPinException(String msg)
            {
                super(msg);
            }
        }
        /*
            自定义异常类
         */
        public class MaoYanException extends Exception {
            public MaoYanException(String msg)
            {
                super(msg);
            }
        }
        /*
            自定义异常类
         */
        public class TeacherException extends Exception{
            public TeacherException(){}
            public TeacherException(String msg)
            {
                super(msg);
            }
        }
        public class Test {
            public static void main(String[] args) {
                Teacher t = new Teacher("老师");
                try {
                    t.prelect();
                } catch (TeacherException e) {
                    System.out.println(e.toString());
                    System.out.println("换老师或者放假");
                }
            }
        }  
    自定义异常:继承Exception和RuntimeException
    因为项目中出现特有的问题,而这些问题本没有被java所描述,所以对于可以按照java的
    封装思想,将特有问题进行自定义封装
    如何进行自定义异常呢?
           因为父类中已经将异常信息的操作做完了,所以子类只需在构造函数中 通过super()
           把异常信息传递给父类进行初始化,子类就可以直接调用父类中的getMessage()获取
           自定义的异常信息
    继承Exception的原因:
           异常体系有一个特点,异常类和异常对象都被抛出,他们都具有可抛性。
           这个可抛性是Throwable体系中的独有特点,只有这个体系中的类和对象
           才可以被throw和throws操作
    代码示例:
        public class Test {
            public static void main(String[] arg)
            {       
                try
                {
                    DemoException d = new DemoException();
                    int result = d.result(5, -2);
                    System.out.println(result);
                }
                catch(FuShuException e)
                {
                    System.out.println(e.toString());
                    System.out.println("出现负数了,值是:" + e.getValue());
                }
                System.out.println("over");
            }
        }
        class DemoException
        {
            public int result(int a, int b)throws FuShuException //方法外部throws关键字声明有可能出问题
            {
                if(b < 0)
                {
                    throw new FuShuException("被除数出现负数",b); //方法内部throw关键字抛出异常
                }
                return a/b;
            }
        }
        class FuShuException extends Exception
        {
            private int value;
            FuShuException(){}
            FuShuException(String msg,int value)
            {
                super(msg);
                this.value = value;
            }
            public int getValue()
            {
                return value;
            }
        }
    RuntimeException:
      Exception中有一个特殊的子类异常,RuntimeException,叫做运行时异常。
    如果在函数内throw(抛出)该异常对象,无需在函数上throws(声明)该异常类;
    如果在函数上声明该异常类,调用者无需处理。编译都通过。
        代码示例一:
        class Demo{
            int div(int a, int b) //此处没有做任何操作,编译通过
            {
                if(b == 0)
                    throw new ArithmeticException("被0除了");
                return a/b;
            }
        }
        class ExceptionDemo{
            public static void main(String[] args)
            {
                Demo d = new Demo();
                int x = d.div(3,0);
                System.out.println("x=" + x);
                System.out.println("over");
            }
        }
        代码示例二:
        class Demo{
            int div(int a, int b) throws ArithmeticException
            {
                return a/b;
            }
        }
        class ExceptionDemo{
            public static void main(String[] args) //此处没有申明异常,编译通过了
            {
                Demo d = new Demo();
                int x = d.div(3,0);
                System.out.println("x=" + x);
                System.out.println("over");
            }
        }
        上述程序之所以不用在函数进行申明,是因为不需要调用者处理。当该异常发生,希望
    程序停止。因为在运行时出现了无法继续运算的情况,希望停止程序后对代码进行修正。
    因此,自定义异常时,如果该异常的产生,无法再继续进行运算,就让自定义异常继承RuntimeException
      代码示例:
        public class Test {
            public static void main(String[] arg)
            {       
                try
                {
                    DemoException d = new DemoException();
                    int result = d.result(5, -2);
                    System.out.println(result);
                }
                catch(FuShuException e)
                {
                    System.out.println(e.toString());
                    System.out.println("出现负数了,值是:" + e.getValue());
                }
                System.out.println("over");
            }
        }
        class DemoException
        {
            public int result(int a, int b) //不需要作处理
            {
                if(b < 0)
                {
                    throw new FuShuException("被除数出现负数",b); //方法内部throw关键字抛出异常
                }
                return a/b;
            }
        }
        class FuShuException extends RuntimeException //继承RuntimeException
        {
            private int value;
            FuShuException(){}
            FuShuException(String msg,int value)
            {
                super(msg);
                this.value = value;
            }
            public int getValue()
            {
                return value;
            }
        }
    异常在子父类中覆盖的体现:
    1:子类在重写父类中的方法时,如果父类方法抛出异常,子类中重写的方法,
       只能抛出父类的异常或者该异常的子类异常
          举例说明:
        class AException extends Exception{}
        class BException extends AException{}
        class CException extends Exception{}
        class Fu{
            void show() throws AException
            {
               
            }
        }
        class Zi{
            /*
              只能抛AException或者AException的子类异常BException
              不能抛CException
             */
            void show()throws AException//
            {               
           
            }
        }
    2:如果父类方法抛出多个异常,那么子类再覆盖该方法时,只能抛出父类异常的子集
    3:如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常
       如果子类方法发生了异常,就必须要进行try处理,绝对不能抛
    常见的异常:
        1  OutOfMemoryError(内存溢出错误)
         堆内存溢出
           方法区溢出
   
    2  StackOverflowError(调用栈溢出错误)
      递归调用出了问题。
      通常递归调用,都要有出口,而没有出口就会出现这个StackOverflowError错误!
   
    3  NoSuchMethodError(没有这个方法错误)
      原来有这个方法,所以依赖这个方法的类就编译通过了,但后来这个方法没了,那么原来依赖它的类只要运行就会出现这个错误。
   
    4  NoClassDefFoundError(没有找到类错误)
      原来依赖的类,现在已经不存在了,就会出现这个异常。

    5  ArithmeticException(算术异常)
      整数除以0

    6  ArrayIndexOutOfBoundsException(数组下标越界异常)
      通常我们也不会越界,但只要一使用循环,就不好控制。

    7 ClassCastException
      错误的强转!
      Person p  = new Person();
      Student s = (Student)p;

    8 IllegalArgumentException
      非法参数异常!public void run(int f) {//参数表示方向,前1、后2、左3、右4
      if(f < 0 || f > 4) {throw new IllegalArgumentException();}
    }

    public void setAge(int age) {
       
    }

    9 NullPointerException
      Person p = null;//没有实例化
        p.getName();//出现空指针异常

------- android培训java培训、期待与您交流! ----------

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics