JavaSE学习笔记(九)(异常)

异常

异常本身是一个,产生异常就是创建异常对象并抛出一个异常对象。
Throwable是超类
java.lang.Throwable:所有错误或者异常的超类
两个子类
1.Exception:编译期异常,进行编译(写代码)java程序出现的异常
2.RuntimeException:运行期异常,java程序运行时期的异常
异常就是小毛病,把异常处理掉,程序可以继续执行
Error:错误
相当于程序得了一个无法治愈的毛病,必须修改源码

编译异常
方法一

 public class demo1 {
    
    
    public static void main(String[] args) throws ParseException {
    
    //把异常跑出去,交给虚拟机来处理
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化日期
        Date date = sdf.parse("1999-02-09");//如果格式不对,jvm会中断运行,把异常打印
        System.out.println(date);
    }
  }

方法二

public class Dem02 {
    
    
    public static void main(String[] args) {
    
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//格式化日期
        Date date = null;
        try {
    
    //这种处理了异常之后,会继续执行代码
            date = sdf.parse("1999-0223");
        } catch (ParseException e) {
    
    
            e.printStackTrace();
        }
        System.out.println(date);
        System.out.println("后续代码");//null
        //后续代码

    }
}

运行期出现异常

public class Yunxing {
    
    
    public static void main(String[] args) {
    
    
        int [] a = {
    
    1,2,3};
        try{
    
    //可能出现异常的代码
            System.out.println(a[3]);
        }
        catch (Exception e){
    
    //异常处理逻辑
            System.out.println(e); //java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
        }
        System.out.println("后续代码");//后续代码
    }
}

Error错误

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        int [] a = new int[1024*1024*1024];//内存溢出
        System.out.println("后续代码");
    }
}

==================================================================

异常产生过程解析

在这里插入图片描述

==============================================================

异常的处理

五个关键字:try/catch/finally/throw/throws

throw关键字
作用:用关键字在指定的方法中抛出指定异常
使用格式:throw new xxxException(异常产生的原因)
注意
1关键字必须写在方法内部
2.后面new的对象必须是Exception或者是Exception的子类对象
3.关键字抛出指定异常,我们必须处理这个异常
关键字后面创建的是RuntimeException或者是RuntimeException子类对象,我们可以不处理,交给JVM处理(打印异常对象,中断程序)
创建的是编译异常,我们必须处理,要么throws要么try。。。catch。。

public class Throw {
    
    
    public static void main(String[] args) {
    
    
        int [] a = null;
        int aa = nul(a,0);
        System.out.println(aa);
    }

    public static int nul(int[] a,int m){
    
    
        if(a==null){
    
    
            throw new NullPointerException("空指针异常");//运行期异常可以不用处理
        }
        else if(m<0||m>2){
    
    
            throw new ArrayIndexOutOfBoundsException("超出索引");
        }
        return a[m];
    }

}

=====================================

Objects非空判断

public class Objects {
    
    
    public static void main(String[] args) {
    
    
        s(null);

    }
    public static void s(Object obj){
    
    
        if(obj==null){
    
    
            throw new NullPointerException("空指针");
        }
        
    //    Objects.requireNonNull(obj);
    }

}

========================================
第一种处理异常:throws关键字(交给别人处理
格式

修饰符 返回值类型 方法名(参数) throws AAAExcepton,BBBExcepton.{
throw new AAAExcepton(“产生原因”);
throw new BBBExcepton(“产生原因”);

}

注意事项
1.throws关键字必须写在方法声明处
2.throws后边声明的异常必须是Exception或者子类
3.如果抛出的多个异常有父子类关系,那么值声明异常即可
4.调用一个声明抛出异常的方法,我们必须处理声明的异常。要么使用throws声明抛出,
要么try…catch自己处理

public class Demo {
    
    
    public static void main(String[] args) throws FileNotFoundException {
    
    
        m("d://a.txt");
    }
    public static void m(String file) throws FileNotFoundException {
    
    
	       //FileNotFoundException是编译异常,抛出了编译异常就必须处理这个异常
            //可以调用throws继续声明抛出FileNotFoundException这个异常对象,让方法调用者处理
        
        if(!file.equals("d://a.tzt")){
    
    
            throw new FileNotFoundException("没有找到文件");
        }
		System.out.println("后续代码");//不能被打印,JVM中断
    }
}

======================================================
第二种处理异常 捕捉异常 try…catch

格式

try{
可能产生异常的代码
}catch(定义一个异常的变量,用来接收try中抛出的异常){
异常处理逻辑
一般工作中,把异常信息记录到一个日志中
}

catch(异常类名 变量名){
}

注意:1.try可以抛出多个异常,用多个catch来处理这些异常对象

public class Demo {
    
    
    public static void main(String[] args) {
    
    

        try{
    
    
            m("d://a.bat");
        }catch(IOException e){
    
    
            System.out.println("catch-传递文件后缀不是.txt");
        }

        System.out.println("后续代码");
    }
    public static void m(String file) throws IOException {
    
    
        if(!file.endsWith(".txt")){
    
    
            throw new IOException("后缀不对");
        }
    }
}
//catch-传递文件后缀不是.txt
//后续代码

====================================================================

Throwable类中定义的三个异常处理的方法

String getMessage() 返回此 throwable 的详细消息字符串
String toString() 返回此 throwable 的简短描述。 。
void printStackTrace() JVM打印异常对象,默认此方法,打印的异常信息是最全面的

public class Demo {
    
    
    public static void main(String[] args) {
    
    

        try{
    
    
            m("d://a.bat");
        }catch(IOException e){
    
    
           // System.out.println("catch-传递文件后缀不是.txt");
            
            //System.out.println(e.getMessage());//打印:后缀不对
            
            //System.out.println(e.toString());//打印:java.io.IOException: 后缀不对
            
            e.printStackTrace();//java.io.IOException: 后缀不对
            //at javayichang.trycatch.Demo.m(Demo.java:22)
            //at javayichang.trycatch.Demo.main(Demo.java:9)
            //后续代码
        }
        System.out.println("后续代码");
    }
    public static void m(String file) throws IOException {
    
    
        if(!file.endsWith(".txt")){
    
    
            throw new IOException("后缀不对");
        }
    }
}

============================================================
finally代码块

格式:try{
}
catch(){
}
finally{
无论是否出现异常,都会被执行;
}

public class Finall {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            readfile("d;//a.txt");
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            System.out.println("资源释放");//输出
        }
    }
    public static void readfile(String filename) throws IOException {
    
    
        if(!filename.endsWith("txt")) {
    
    
            throw new IOException();
        }

    }
}

======================================================

多个异常

public class Demo1 {
    
    
    public static void main(String[] args) {
    
    
        //1.多个异常,逐个处理
       /*try {
            int[] a = {1, 2, 3};
            System.out.println(a[3]);
        } catch (ArrayIndexOutOfBoundsException e) {
           // e.printStackTrace();
            System.out.println(e.getMessage());//Index 3 out of bounds for length 3
        }

       try{
           ArrayList<Integer> integers = new ArrayList<>();
           integers.add(1);
           System.out.println(integers.get(4));
        }catch(IndexOutOfBoundsException e){
           //e.printStackTrace();
           System.out.println(e.getMessage());//Index 4 out of bounds for length 1
       }

       System.out.println("后续代码");//后续代码
        */

        //2.多个异常,一次捕捉,多次处理
        //注意:如果存在子父类,那么子类必须在上面
        //ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
        /*try {
            int[] a = {1, 2, 3};
            System.out.println(a[3]);
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(1);
            System.out.println(integers.get(4));

       } catch (ArrayIndexOutOfBoundsException e) {
            // e.printStackTrace();
            System.out.println(e.getMessage());//Index 3 out of bounds for length 3
        }catch(IndexOutOfBoundsException h){
            //e.printStackTrace();
            System.out.println(h.getMessage());
        }

        System.out.println("后续代码");//后续代码

*/


        //一次捕获异常,一次处理异常
        try {
    
    
            int[] a = {
    
    1, 2, 3};
            System.out.println(a[3]);
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(1);
            System.out.println(integers.get(4));

        } catch (ArrayIndexOutOfBoundsException e) {
    
    //父类,可以接收自己的对象,也可以接收子类对象。
            // e.printStackTrace();
            System.out.println(e.getMessage());//Index 3 out of bounds for length 3
        }
        System.out.println("后续代码");//后续代码

    }
}
//运行期异常可以不用处理,交给虚拟机处理

======================================================
finally中有return语句,则永远返回finally中的return对象

public class finanlly {
    
    
    public static void main(String[] args) {
    
    
        int num =get();
        System.out.println(num);//100

    }
    public static int get(){
    
    
        try{
    
    
            int a=10;
        }catch(Exception e){
    
    
            System.out.println(e.toString());
        }finally {
    
    
            int a = 100;
            return a;
        }
    }
}

======================================================

子父类异常

1.如果父类抛出多个异常,子类重写父类该方法时,抛出和父类相同的异常或者父类异常的子类或者不抛出
2.父类方法没有抛出异常,子类重写父类该方法时也不能抛出异常,此时子类产生异常,只能捕获处理,不能抛出

public class FU {
    
    
    public void show01() throws NullPointerException,ClassCastException{
    
    }
    public void show02() throws IndexOutOfBoundsException{
    
    }
    public void show03() throws IndexOutOfBoundsException{
    
    }
    public void show04(){
    
    }
}
class Zi extends FU{
    
    
    //子类重写父类异常时,抛出和父类相同的异常
    public void show01() throws NullPointerException,ClassCastException{
    
    }
    //子类重写父类方法时,抛出父类异常的子类
    public void show02() throws ArrayIndexOutOfBoundsException{
    
    }
    //子类重写父类异常时,不抛出异常
    public void show03(){
    
    }
    //父类没有抛出异常,子类重写父类该方法时也不能抛出
    //如果子类产生异常,只能捕获,不能抛出
    public void show04(){
    
    
        try{
    
    
            throw new Exception("编译期异常");
        }catch(Exception e){
    
    
            e.printStackTrace();;
        }
    }
}

================================================================

自定义异常类

java提供的异常类不够我们使用,需要自己定义一些异常类
格式

注意
1.自定义异常类一般都是以Exception结尾,说明类是一个异常类
2.自定义异常类,必须继承Exception或者RuntimeException
继承Exception,那么自定义的类就是编译器异常,如果方法内部抛出了编译期异常,就必须处理这个异常,要么throws要么try。。。catch。。
继承RuntimeException,那么定义的异常类就是一个运行期异常,无需处理,交给虚拟机处理(中断)

public class RegisterException extends Exception{
    
    
      //添加一个空参数的构造方法
      public RegisterException(){
    
    
      }
	  
      //添加一个带异常信息的构造方法
      public RegisterException (String messsge){
    
    
         super(messsge);
      }
}

===================================================

自定义异常类练习

模拟注册操作,如果用户名存在,抛出异常提示
分析
1.使用数组保存已经注册过的用户名(数据库)
2.使用Scanner获取用户输入的用户名(前端,页面)
3.定义一个方法,对用户输入的名字进行判断

public class RegisterException extends Exception{
    
    

        //添加一个空参数的构造方法
        public RegisterException(){
    
    
        }

        //添加一个带异常信息的构造方法
        public RegisterException (String messsge){
    
    
            super(messsge);
        }

}
public class Demo01 {
    
    
     static  String[] usernames = {
    
    "张三","李四","王五"};

    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.next();
        check(username);
    }
    public static void check(String username){
    
    
        for (String name : usernames) {
    
    
            if(name.equals(username)){
    
    
                try {
    
    
                    throw new RegisterException("亲,该用户名已经被注册");
                } catch (RegisterException e) {
    
    
                    e.printStackTrace();
                    return;
                }
            }
        }
        System.out.println("注册成功");
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45511599/article/details/108909719
今日推荐