Java异常知识点总结

异常概览

异常分为Exception和Error,Exception可以通过try-catch块处理,而Error是指程序发生错误,必须修改,如内存溢出

public class ErrorAndException {
    public static void main(String[] args) {
        int[] ar1 = new int[3];
        try{
            System.out.println(ar1[3]);
        }catch(Exception e){
            System.out.println("Exception handling:");
            e.printStackTrace();
            System.out.println("Exception handled.");
        }
        /*
        Error示例:
        int[] ar2 = new int[Integer.MAX_VALUE];
        程序运行产生错误:
        Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	    at demo07.demo02.main(demo02.java:21)
         */

    }
}

throw字段

用throw在方法中抛出指定异常
格式:throw new XXException("…");
注意:

  1. throw必须写在方法内部
  2. throw抛出指定的异常对象,我们就必须处理这个异常对象
  3. throw抛出RuntimeException或者其子类对象异常,我们可以不处理,默认交给JVM处理
  4. throw抛出编译异常,我们必须处理这个异常,要么throws,要么try-catch
public class Demo02Throw {
    public static void main(String[] args) {
        int[] ar1 = null;
        getElement(ar1, 0);
        int[] ar2 = new int[0];
        getElement(ar2, 0);
    }

    public static int getElement(int[] ar, int index) {
        if (ar == null) {
            throw new NullPointerException("数组引用为null");   //NullPointerException是一个运行期异常
        }
        if (index >= ar.length || index < 0) {
            throw new IndexOutOfBoundsException("数组越界");
        }
        return ar[index];
    }
}

Objects类方法

public class Demo03Objects {
    public static void main(String[] args) {
        method(null);
    }
    public static void method(Object obj){
        Objects.requireNonNull(obj, "空对象");
    }
}

throws字段

throws字段用于函数声明可能抛出的异常:

public class Demo04Throws {
    public static void main(String[] args) throws IOException { //FileNotFoundException是IOException的子类,只需抛出父类异常
        readFile("d:\\a/txt");
    }
    public static void readFile(String fileName) throws IOException { //readFile()将FileNotFoundException抛出
        if(!fileName.equals("c:\\\\a.txt")){
            throw new FileNotFoundException("文件路径不是c:\\a.txt"); //throw抛出编译异常FileNotFoundException,我们必须处理这个异常,要么throws,要么try-catch
        }
        if(!fileName.endsWith(".txt")){
            throw new IOException("文件不是txt");
        }
    }
}

try-catch块

try-catch块用于捕获和处理异常:

public class Demo05TryCatch {
    public static void main(String[] args) {
        System.out.println("s:\\");
        try {
            //可能发生异常的代码
            readFile("d:\\a.txt");
        } catch (IOException e) {
            //异常处理逻辑
            System.out.println("异常处理:");
            e.printStackTrace();
            System.out.println(e.getMessage());
        } finally {
            /*
            finally必须和try一起使用
            finally一般用于资源释放(IO)
             */
            //do something
        }
        System.out.println("后续代码");
    }

    public static void readFile(String fileName) throws IOException { //readFile()将FileNotFoundException抛出

        if (!fileName.endsWith(".txt")) {
            throw new IOException("文件不是txt");
        }

        if (!fileName.equals("c:\\a.txt")) {
            throw new FileNotFoundException("文件路径不是c:\\a.txt"); //throw抛出编译异常FileNotFoundException,我们必须处理这个异常,要么throws,要么try-catch
        }
    }
}

多个异常的处理

public class Demo06MultiException {
    public static void main(String[] args) {
        method2();
    }

    //多个异常分别处理
    public static void method1() {
        List<Integer> list = new ArrayList<>();
        try {
            list.get(3);
        } catch (Exception e) {
            e.printStackTrace();
        }
        int[] ar = new int[3];
        try {
            System.out.println(ar[3]);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //多个异常一次捕获,多次处理
    public static void method2() {
        List<Integer> list = new ArrayList<>();
        int[] ar = new int[3];
        try {
            list.get(3);
            System.out.println(ar[3]);
        } catch (ArrayIndexOutOfBoundsException e) {    //子类异常必须在父类异常之前被捕获
            System.out.println("ArrayIndexOutOfBoundsException异常处理");
        } catch (IndexOutOfBoundsException e) {
            System.out.println("IndexOutOfBoundsException异常处理");
        } finally {
            System.out.println("finally子句");
        }
    }
    //多个异常一次捕获,一次处理
    public static void method3() {
        try {
            List<Integer> list = new ArrayList<>();
            int[] ar = new int[3];
            list.get(3);
            System.out.println(ar[3]);
        } catch (Exception e) {    //子类异常必须在父类异常之前被捕获
            System.out.println("Exception异常处理");
        }
    }
}

finally子句

public class Demo07Finally {
    public static void main(String[] args) {
        method();
    }
    public static int method(){
        try{
            return 1;
        } catch(Exception e){
            e.printStackTrace();
        } finally { //只要finally中有return语句,永远返回finally中的结果
            return 3;
        }
    }
}

子类和父类的异常抛出

  • 如果父类方法抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者不抛出异常
  • 父类没有抛出异常,子类也不能抛出异常。这时子类产生异常,只能捕获,不能抛出
class SuperClass {
    public void method1() throws NullPointerException {
    }

    public void method2() throws Exception {
    }

    public void method3() {
    }

}

class SubClass extends SuperClass {
    public void method1() throws NullPointerException {
    }
    //    public void method1() throws Exception {} 报错
    public void method2() throws NullPointerException { //可以抛出Exception的子类异常
    }

    public void method3() {
    }
}

自定义异常

自定义异常一般是以Exception结尾,说明该类是一个异常
自定义异常,必须继承Exception或者RuntimeException:
1.继承Exception,那么自定义的异常类是一个编译期异常,一经抛出必须处理
2.继承RuntimeException,那么自定义的异常类是一个运行期异常,可以不处理
自定义异常的格式通常如下:

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

模拟用户注册练习

/*
1.用集合保存已经注册用户名
2.使用Scanner获取用户输入的注册用户名
3.使用方法对用户名进行注册
 */
public class Demo10ExceptionExercise {
    private static Set<String> registeredNames = new HashSet<>();

    public static void main(String[] args) throws RegisterException {
        Scanner sc = new Scanner(System.in);
        System.out.println("输入注册的用户名:");
        String userName = sc.next();
        register(userName);
    }

    public static void register(String userName) throws RegisterException {
        if(registeredNames.contains(userName))
            throw new RegisterException();
        registeredNames.add(userName);
    }
}

class RegisterException extends Exception {
    public RegisterException() {
        super();
    }

    public RegisterException(String message) {
        super(message);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值