异常




 

 



package
oyichang; /* * 1、异常是什么? * 第一,异常模拟的是现实世界中"不正常的"事件 * 第二,java中采用"类"去模拟异常 * 第三,类是可以创建对象的 * NullPointerException e = 0x1234; * e是引用类型,e中保存的内存地址指向堆中的"对象" * 这个对象一定是NullPointerException类型 * 这个对象就表示真实存在的异常事件 * NullPointerException是一类异常。 * * "抢劫"就是一类异常 --->类 * "张三被抢劫"就是一个异常事件 --->对象 * * 2、异常机制的作用? * java语言为我们提供一种完善的异常处理机制 * 作用是:程序发生异常事件之后,为我们输出详细的信息, * 程序员通过这个信息,可对程序进行一些处理,使程序更加健壮 */ public class ExceptionTest01 { public static void main(String[] args) { int a = 10; int b = 0; int c = a/b; //上面的代码出现了异常,没有处理, //下面的代码不会执行,直接退出了JVM System.out.println("Hello World!"); } } /* * 以上程序编译通过了,但运行时出现了异常,表示发生某个异常事件 * * 本质:程序执行过程中发生了算数异常这个事件, * JVM为我们创建了一个ArithmeticException类型的对象 * 并且这个对象中包含了详细的异常信息, * 且JVM将这个对象中的信息输出到控制合。 * JVM向控制台输出如下的信息: * * Exception in thread "main" java.lang.ArithmeticException: / by zero * at oyichang.ExceptionTest01.main(ExceptionTest01.java:26) */
package oyichang;

/*
 * 处理异常有两种方式:
 *         1.声明抛出    throws
 *         2.捕捉    try...catch...
 * 
 * 以下程序演示第一种方式:声明抛出,
 * 在方法声明的位置上使用throws关键字向上抛出异常。
 */
import java.io.*;

public class ExceptionTest03 {

    //public static void main(String[] args) throws FileNotFoundException{ 可以
    //public static void main(String[] args) throws IOException{  更可以
    public static void main(String[] args) throws Exception{  //绝对可以
        
        //创建文件输入流,读取文件
        //思考:java编译器是如何知道以下的代码执行过程中可能出现异常,
        //java编译器是如何知道这个异常发生的几率比较高呢?
        //java编译器不是那么智能,因为FileInputStream这个构造方法在
        //声明的位置上使用了throws FileNotFoundException;
        FileInputStream fis = new FileInputStream("c:/ab.txt");
    }

}
package oyichang;

import java.io.*;

public class ExceptionTest04 {

    public static void main(String[] args) throws FileNotFoundException{
        m1();
        
        //使用throws处理异常不是真正处理异常而是推卸责任
        //谁调用的就会抛给谁
        //上面的m1方法如果出现了异常,因为采用的是上抛,给了JVM,JVM遇到这个异常就会退出JVM,下面的这个代码不会执行
        System.out.println("Hello World");
    }
    
    public static void m1() throws FileNotFoundException{
        m2();
    }
    
    public static void m2() throws FileNotFoundException{
        m3();
    }
    
    public static void m3() throws FileNotFoundException{
        new FileInputStream("c:/ab.txt"); //FileInputStream构造方法声明位置上使用throws(向上抛)
    }

}

/*
//在程序运行过程中发生了FileNotFoundException类型的异常
//JVM为我们创建了一个FileNotFoundException类型的对象
//该对象中携带以下的信息
//JVM负责将该对象的信息打印到控制台
//并且JVM停掉了程序的运行。
Exception in thread "main" java.io.FileNotFoundException: c:\ab.txt (系统找不到指定的文件。)
    at java.io.FileInputStream.open(Native Method)
    at java.io.FileInputStream.<init>(FileInputStream.java:106)
    at java.io.FileInputStream.<init>(FileInputStream.java:66)
    at oyichang.ExceptionTest04.m3(ExceptionTest04.java:25)
    at oyichang.ExceptionTest04.m2(ExceptionTest04.java:21)
    at oyichang.ExceptionTest04.m1(ExceptionTest04.java:17)
    at oyichang.ExceptionTest04.main(ExceptionTest04.java:8)
 */
package oyichang;

/*
 * 处理异常的第二种方式:捕捉    try...catch...
 * 
 *     语法:
 *         try{
 *             可能出现异常的代码;
 *         }catch(异常类型1 变量){
 *             处理异常的代码;
 *         }catch(异常类型2 变量){
 *             处理异常的代码;
 *         }...
 * 
 *     1、catch语句块可以写多个
 *     2、但是从上到下catch,必须从小类型异常到大类型异常进行捕捉
 *     3、try...catch...中最多执行1个catch语句块。执行结束之后try...catch...就结束了
 */

import java.io.*;
public class ExceptionTest05 {

    public static void main(String[] args) {

        //编译通过
        /*
        try{            
            //异常:FileNotFoundException
            FileInputStream fis = new FileInputStream("c:/ab.txt");
            
        }catch(ArithmeticException e){ //捕获的是算术异常,异常没被处理
            
        }catch(FileNotFoundException e){ //编译通过
            
        }
        */

        //编译通过,这个方法比下面的更细腻,更好
        /*
        try{            

            FileInputStream fis = new FileInputStream("c:/ab.txt");
            
            fis.read();
            
        }catch(FileNotFoundException e){ //捕获FileNotFoundException
            
        }catch(IOException e){  //捕获IOException
            
        }
        */
        
        //编译通过,因为IOException包含FileNotFoundException,但太空泛
        /*
        try{            

            FileInputStream fis = new FileInputStream("c:/ab.txt");
            
            fis.read();
            
        }catch(IOException e){
            
        }
        */
        
        //编译无法通过
        //catch可以写多个,但是必须从上到下,从小到大捕捉
        /*
        try{            

            FileInputStream fis = new FileInputStream("c:/ab.txt");
            
            fis.read();
            
        }catch(IOException e){
            
        }catch(FileNotFoundException e){
            
        }
        */
    }

}
package oyichang;

import java.io.*;

public class ExceptionTest06 {

    //编译无法通过
    //IOException没有处理
    /*
    public static void main(String[] args) throws FileNotFoundException{

        FileInputStream fis = new FileInputStream("abc");
        fis.read();
    }
    */
    
    //通过
    /*
    public static void main(String[] args) throws FileNotFoundException, IOException{

        FileInputStream fis = new FileInputStream("abc");
        fis.read();
    }
    */

    //通过,IOException是大类型
    /*
    public static void main(String[] args) throws IOException{

        FileInputStream fis = new FileInputStream("abc");
        fis.read();
    }
    */
    
    public static void main(String[] args){
        try{            

            //程序执行到此发生了FileNotFoundException类型的异常
            //JVM会自动创建一个FileNotFoundException类型的对象,将该对象的内存地址赋值给catch语句块中的e变量
            FileInputStream fis = new FileInputStream("abc"); //没有这个文件
            
            //上面的代码出现了异常,try语句块的代码不再继续执行,直接进入catch语句块中执行
            System.out.println("TTT"); //不执行
            
            fis.read();  //不执行
        
        }catch(FileNotFoundException e){ //e内存地址指向堆中的那个对象是"FileNotFoundException类型的"事件
            
            System.out.println("读取的文件不存在!"); //执行
            
            //FileNotFoundException将Object中的toString方法重写
            System.out.println(e); //java.io.FileNotFoundException: abc(系统找不到指定的文件。)
        
        }catch(IOException e){
        
            System.out.println("其他IO异常"); //不执行
            
        }
        
        System.out.println("ABC");
    }
}
package oyichang;

import java.io.*;

/*
 * 关于getMessage和printStackTrace方法的应用
 */
public class ExceptionTest07 {

    public static void main(String[] args) {

        try{
            
            FileInputStream fis = new FileInputStream("c:/abc.txt");
            
            //JVM为我们执行了一下这段代码
            //FileNotFoundException e = new FileNotFoundException(c:\abc.txt (系统找不到指定的文件。))
            
        }catch(FileNotFoundException e){
            
            //打印异常堆栈信息
            //一般情况下都会使用该方法去调试程序
            e.printStackTrace();
            
            /*
            java.io.FileNotFoundException: c:\abc.txt (系统找不到指定的文件。)
                at java.io.FileInputStream.open(Native Method)
                at java.io.FileInputStream.<init>(FileInputStream.java:106)
                at java.io.FileInputStream.<init>(FileInputStream.java:66)
                at oyichang.ExceptionTest07.main(ExceptionTest07.java:14)
            */
            
            String msg = e.getMessage(); //c:\abc.txt (系统找不到指定的文件。)
            
            System.out.println(msg);
        }
        
        //这段代码会执行
        System.out.println("ABC");
    }

}
package oyichang;

import java.io.FileInputStream;

/*
 * 关于finally语句块
 *         1、finally语句块可以直接和try语句块联用。try...finally
 *         2、try...catch...fina11y也可以
 *         3、在finally语句块中的代码是一定会执行的
 */

import java.io.*;

public class ExceptionTest08 {

    public static void main(String[] args) throws Exception{

        /*
        try{
            
            System.out.println("ABC");
            return; //按理说会返回,实际不返回
            
        }finally{
            
            System.out.println("Test");
        }
        //输出ABC Test
        */
    
        /*
        try{
        
            FileInputStream fis = new FileInputStream("Test.java"); //当前路径下没有此文件
        
            //不会执行
            System.out.println("TTTT");
        
        }finally{
        
            //会执行
            System.out.println("AAAA");
        
        }
        */
        
        
        //只要在执行finally语句块之前退出JVM,则finally语句块不会执行
        try{
            
            //退出JVM
            System.exit(0);
            
        }finally{
            
            //不会执行
            System.out.println("finally...");
        }
    }

}
package oyichang;

public class ExceptionTest09 {

    public static void main(String[] args) {

        int i = m1();
        System.out.println(i); //10
    }

    public static int m1(){
        int i = 10;
        try{
            return i; //10
        }finally{
            i++;
            System.out.println("m1的i = " + i); //11
        }
        
        //以上代码的执行原理
        /*
        int i = 10;
        try{
            int temp = i;
            return temp;
        }finally{
            i++;
            System.out.println("m1的i = " + i);
        }
        */
    }
}
package oyichang;

import java.io.*;

public class ExceptionTest10 {

    public static void main(String[] args) {

        //必须在外边声明
        FileInputStream fis = null;
        
        try{
            
            fis = new FileInputStream("fds.java");
            
        }catch(FileNotFoundException e){
            
            e.printStackTrace();
            
        }finally{
            
            //为了保证资源一定释放
            if(fis != null){
                try{
                    fis.close();
                }catch(IOException e){
                    e.printStackTrace();
                }
            }
        }
    }

}
package oyichang;

import java.io.FileNotFoundException;
import java.io.IOException;

/*
 * 重写的方法不能比被重写的方法抛出更宽泛的异常
 */
/*
class A {

    public void m1(){}
}

class B extends A{
    
    //子类永远无法抛出比父类更多的异常
    public void m1() throws Exception{}
}
*/

class A{
    //public void m1() throws FileNotFoundException{}
    public void m1() throws IOException{}
}

class B extends A{
    //抛出的异常更宽泛,错误
    //public void m1() throws IOException{}
    public void m1() throws FileNotFoundException{}
}

 

 

package ozidingyiyichang;
/*
 * 自定义"无效名字异常"
 *         1、编译时异常,直接继承Exception
 *         2、运行时异常,直接继承RuntimeException
 */
public class IllegalNameException extends Exception{ //编译时异常
//public class IllegalNameException extends RuntimeException{ //运行时异常
    
    //定义异常一般提供两个构造方法
    public IllegalNameException(){}
    
    public IllegalNameException(String msg){
        super(msg);
    }

}
package ozidingyiyichang;

public class CustomerService {

    public void register(String name) throws IllegalNameException{
        
        //完成注册
        if(name.length() < 6){
            //异常
            //创建异常对象
            //IllegalNameException e = new IllegalNameException("用户名长度不能少于6位");
            
            //手动抛出异常
            //throw e;
            
            //这不能用try...catch,因为需要展示异常信息,所以要在入口写抛出异常
            throw new IllegalNameException("用户名长度不能少于6位");
        }
        
        //如果代码能执行到此处,证明用户名是合法的
        System.out.println("注册成功!");
    }
}
package ozidingyiyichang;

public class Test {

    public static void main(String[] args) {

        //假如用户提供的用户名如下
        String username = "jack";
        
        //注册
        CustomerService cs = new CustomerService();
        
        try{
            
            cs.register(username);
            
        }catch(IllegalNameException e){
            
            System.out.println(e.getMessage());
        }
        
    }

}

 

posted @ 2020-08-13 23:17  Lerresino  阅读(131)  评论(0)    收藏  举报