异常 try catch finally throw throws

1.异常常用方法

/**
 * 异常常用的方法
 */
public class ExceptionApiDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了");        
        try {
            String str = "a";
            System.out.println(Integer.parseInt(str));
        } catch (Exception e) {
            /*
             * 将当前的错误信息输出到控制台上
             */
            e.printStackTrace();
            //获取错误消息
            String message = e.getMessage();
            System.out.println(message);
        }        
        System.out.println("程序结束了");
    }
}

2.异常处理机制中的try-catch

/**
 * java异常处理机制中的try-catch
 * 语法:
 * try{
 *     程序代码片段
 * }catch(XXXException e){
 *     当try中出现XXXException后的解决代码
 * }
 * 或
 * try{
 * 
 * }finally{
 * 
 * }
 */
public class TryCatchDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了...");
        try {
//            String str = null;
//            String str = "";
            String str = "a";
            /*
             * 当JVM执行程序是发现某个错误时就会实例化对应的异常实例并将程序执行过程设置好,然后将该异常抛出.
             * 此时若没有异常处理机制,该异常会被继续抛出到当前方法之外(这里就抛出到main方法外).若最终抛给虚拟机,则
             * 会直接中断.
             */
            System.out.println(str.length());            
            System.out.println(str.charAt(0));            
            System.out.println(Integer.parseInt(str));
            /*
             * 在try语句块中出错以下的代码都
             * 不会被执行.
             */
            System.out.println("!!!!!!");        
        }catch(NullPointerException e) {
            System.out.println("出现了空指针!");
        /*
         * catch是可以定义多个的,针对try中出现
         * 的不同异常有不同处理方式时可以分别
         * 捕获它们
         */
        }catch(StringIndexOutOfBoundsException e) {
            System.out.println("出现了下标越界!");
        /*
         * 可以在最后一个catch处捕获Exception,
         * 来避免因为一个未捕获的异常导致程序
         * 中断.
         */
        }catch(Exception e) {
            System.out.println("反正就是出了个错!");
        }        
        System.out.println("程序结束了!");
    }
}

3.自定义异常

/**
 * 自定义异常
 * 自定义异常通常用来定义业务逻辑问题,这种异常java是没有提供的.
 * 
 * 自定义异常几步:
 * 1:定义类,类名应当做到见名知意
 * 2:需要继承自Exception
 * 3:提供所有构造方法
 */
public class IllegalAgeException extends Exception{
    private static final long serialVersionUID = 1L;
    public IllegalAgeException() {
        super();
    }
    public IllegalAgeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    public IllegalAgeException(String message, Throwable cause) {
        super(message, cause);
    }
    public IllegalAgeException(String message) {
        super(message);
    }
    public IllegalAgeException(Throwable cause) {
        super(cause);
    }    
}

4.异常的抛出

/**
 * 使用当前类测试异常的抛出
 */
public class Person {
    private int age;
    public int getAge() {
        return age;
    }
    public void setAge(int age) throws IllegalAgeException{
        if(age<0||age>100) {
            /*
             * 当一个方法中使用throw抛出一个异常时就要在当前方法上使用throws声明
             * 该异常的抛出告知调用者去解决该异常
             * 注:只有抛出RuntimeException及其子类型异常时可以不这样做
             */
            throw new IllegalAgeException("年龄不合法");
        }
        this.age = age;
    }    
}
/**
 * 异常的抛出
 * throw关键字,用于主动抛出一个异常.
 * 通常以下情况我们会主动抛出异常:
 * 1:程序遇到一个满足语法要求,但是不满足业务逻辑要求时,我们可以主动抛出异常告知调用
 *   方不应当这样做.
 * 2:程序确实出现了异常,但是该异常不应当在当前代码片段被解决时可以对外抛出给调用方解决.  
 */
public class ThrowDemo {
    public static void main(String[] args) {        
        Person p = new Person();
        /*
         * 当调用一个含有throws声明异常抛出的方法时,编译器要求必须处理该异常,否则编译不通过.
         * 处理异常的方式有两种:
         * 1:使用try-catch捕获并处理该异常
         * 2:在当前方法上继续使用throws声明异常的抛出
         */
        try {
            p.setAge(10);//满足语法,但是不满足业务要求
        } catch (IllegalAgeException e) {
            System.out.println("出错了!");
        }
        System.out.println(p.getAge());    
    }
}
/**
 * 子类重写父类含有throws声明异常抛出的方法时
 * 对throws的重写规则
 */
public class ThrowsDemo {
    public void dosome() throws IOException,AWTException {        
    }
}

class SubClass extends ThrowsDemo{
//    public void dosome() throws IOException,AWTException {    
//    }
    //允许不再抛出任何异常
//    public void dosome(){        
//    }
    //允许仅抛出部分异常
//    public void dosome() throws IOException{
//    }    
    //允许抛出父类方法抛出异常的子类型异常
//    public void dosome() throws FileNotFoundException {    
//    }
    
    /*
     * 不允许抛出额外异常,即:超类方法没有的异常,也不存在继承关系的异常
     */
//    public void dosome() throws SQLException{    
//    }
    /*
     * 不允许抛出父类方法抛出异常的父类型异常
     */
//    public void dosome() throws Exception{    
//    }
} 

5.finally块

/**
 * finally块
 * finally块是异常处理机制中的最后一部分,它可以直接跟在try语句块之后或者最后一个catch块之后.
 * finally可以保证只要程序执行到try当中,无论是否出现异常,finally中的代码都必定执行.
 * 
 * 通常我们可以将释放资源这样的必须操作的代码放在这里.
 */
public class FinallyDemo {
    public static void main(String[] args) {
        System.out.println("程序开始了...");
        try {
            String str = "";
            System.out.println(str.length());
            return;
        } catch (Exception e) {
            System.out.println("出错了!");
        } finally {
            System.out.println("finally代码执行了!");
        }
        System.out.println("程序结束了");
    }
}
/**
 * 在IO中使用异常处理机制
 */
public class FinallyDemo2 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("fos.dat");
            fos.write(1);
        }catch(Exception e) {
            System.out.println("出错了!");
        }finally {
            try {
                if(fos!=null) {
                    fos.close();
                }
            } catch (Exception e) {
            }
        }        
    }
}
/**
 * 面试中finally常见问题
 * 请分别说明final,finally,finalize
 * finalize是Object定义的方法,该方法是当GC释放该对象资源时调用此方法,调用后该对象即被释放.
 * 注意,此方法若重写,里面不应当有耗时的操作.
 */
public class FinallyDemo3 {
    public static void main(String[] args) {
        System.out.println(test("0")+","+test(null)+","+test("")    );//3,3,3,finally中有return最终都是在finally块中return
    }    
    public static int test(String str) {
        try {
            return str.charAt(0)-'0';
        } catch(NullPointerException e) {
            return 1;
        } catch (Exception e) {
            return 2;
        } finally {
            return 3;
        }
    }
}

6.AutoCloseable

/**
 * JDK7之后推出了一个特性:AutoCloseable
 * 该特性旨在让我们在源代码中可以以更简化的代码完成在finally中关闭流.
 */
public class AutoCloseableDemo {
    public static void main(String[] args) {
        try(
            /*
             * 在这里定义的流最终会被编译器该为
             * 在finally中关闭.
             * 只有实现了AutoCloseable接口的类才
             * 能在这里定义并实例化.
             * 流和RandomAccessFile都实现了该接口
             */
            FileOutputStream fos = new FileOutputStream("fos.dat");
        ){
            fos.write(1);
        }catch(Exception e) {
            System.out.println("出错了!");
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/hello4world/p/12147601.html