java內部類,異常--09

內部類

內部類的訪問規則:
1,內部類可以直接訪問外部類中的成員,包括私有
格式:外部類名.this

2,外部類要訪問內部類,必須建立內部類對象。
訪問格式:
1,當內部類定義在外部類的成員位置上,而且非私有,可以在外部其他類中直接建立內部類對象。
格式:外部類名.內部類 變量名 = 外部類對象.內部類對象;
Outer.Inner in = new Outer().new Inner();

2,當內部類在成員位置上,就可以被成員修飾符修飾
比如,private:將內部類在外部類中進行封裝。
static:內部類可以被靜態修飾,就具備了靜態的特性
當內部類被static修飾後,只能直接訪問外部類中的靜態成員。出現了訪問侷限。

在外部其他類中,如何直接訪問靜態內部類的非靜態成員呢?
new Outer.Inner().function();

在外部其他類中,如何直接訪問靜態內部類的靜態成員呢?
Outer.Inner.function();

注意:
當內部類中定義了靜態成員,該內部類必須是靜態的。
當外部類中的靜態方法訪問到內部類時,內部類也必須是靜態的。

class Outer
{
    private int x=3;

    class Inner //內部類
    {
        int x=4;
        void function()
        {
            int x=6;
            System.out.println("inner:"+Outer.this.x);
            //打印結果是3,裏面換成this.x打印的是4,直接打印x是6
        }
    }

    void method()
    {
        Inner in = new Inner();
        in.function();
    }
}

class InnerClassDemo
{
    public static void main(String[] args)
    {
        //Outer out = new Outer();
        //out.method();

        //直接訪問內部類中的成員
        Outer.Inner in = new Outer().new Inner();
        in.function();
    }
}

內部類定義在局部時,
1,不可以被成員修飾符修飾。如static
2,可以直接訪問外部類中的成員,因爲還持有外部類中的引用
但是不可以訪問它所在的局部中的變量,只能訪問被final修飾的局部變量。

class Outer
{
    int x = 3;
    void method(final int a)
    {
        final int y = 4;
        class Inner
        {
            void function()
            {
                System.out.println(a);
            }
        }   

        new Inner().function();
    }
}

class InnerClassDemo3
{
    public static void main(String[] args)
    {
        //new Outer().method();
        Outer out = new Outer();
        out.method(7);
        out.method(8);
    }
}

匿名內部類

1,匿名內部類其實就是內部類的簡寫格式。
2,定義匿名內部類的前提:
內部類必須是繼承一個類或者實現接口
3,匿名內部類的格式:new 父類或者接口(){定義子類的內容}
4,其實匿名內部類就是一個匿名子類對象。帶內容的對象。
5,匿名內部類中定義的方法最好不要超過三個。

abstract class AbsDemo
{
    abstract void show();
}

class Outer
{
    int x = 3;
    /*
    class Inner extends AbsDemo
    {
        void show()
        {
            System.out.println("method:"+x);
        }
    }
    */
    public void function()
    {
        //new Inner().show();
        new AbsDemo()//匿名內部類
        //AbsDemo ab = new AbsDemo()
        {
            void show()
            {
                System.out.println("x="+x);

            }
        }.show();

    }
}

class InnerClassDemo4
{
    public static void main(String[] args)
    {
        new Outer().function();
    }
}

這裏寫圖片描述

練習:

class Test
{
    //補足代碼,通過匿名內部類。
    /*
    static class Inner implements Inter
    {
        public void method()                //這是有名字的方法,效果與下面的匿名方法一樣
        {
            System.out.println("method run");
        }
    }
    */
    static Inter function()
    {
        return new Inter()
        {
            public void method()
            {
                System.out.println("method run");
            }
        };
    }
}

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

        //Test.function():Test類中有一個靜態的方法function。
        //.method():function這個方法運算後的結果是一個對象,而且是一個Inter類型的對象。
        //因爲只有是Inter類型的對象,纔可以調用method方法。
        Test.function().method();


        Inter in = Test.function();
        in.method();

    }


}

這裏寫圖片描述

異常

異常:程序在運行時出現的不正常情況。
異常由來:問題也是現實生活中一個具體的事物,也可以通過java的類的形式進行描述,並封裝成對象。 也就是java對不正常情況進行描述後的對象體現。

對於問題的劃分:一種是嚴重的問題,一種是非嚴重的問題。
對於嚴重的,java通過Error類進行描述。
對於Error一般不編寫針對性的代碼對其進行處理。
對於非嚴重的,java通過Exception類進行描述。
對於Exception可以使用針對性的處理方式進行處理。

無論Error或者Exception都具有一些共性內容
比如:不正常情況的信息:引發原因等

Throwable
|–Error
|–Exception

2,異常的處理

java提供了特有的語句進行處理

try
{
需要被檢測的代碼
}
catch(異常類 變量)
{
處理異常的代碼;(處理方式)
}
finally
{
一定會執行的語句;
}

3,對捕獲到的異常對象進行常見方法操作
String getMessage():獲取異常信息

class Demo
{
    int div(int a,int b)
    {                                           
        return a/b;
    }
}

class ExceptionDemo
{
    public static void main(String[] args)
    {
        Demo d = new Demo();
        try
        {
            int x = d.div(4,0);
            System.out.println("x="+x);

        }
        catch(Exception e)//Exception e = new ArithemeticException();
        {
            System.out.println("feifa");
            System.out.println(e.getMessage());//   /by zero
            System.out.println(e.toString());//異常名稱:異常信息

            e.printStackTrace();//異常名稱,異常信息,異常出現的位置。
                                //其實jvm默認的異常處理機制,就是在調用printStackTrace方法。
                                //打印異常的堆棧的跟蹤信息。

        }
        System.out.println("over");
    }
}

這裏寫圖片描述

在函數上聲明異常。
便於提高安全性,讓調用者進行處理,不處理編譯失敗。
1,要麼拋出去

class Demo
{
    int div(int a,int b) throws Exception//在功能上通過throws的關鍵字聲明瞭
                                         //該功能可能會有的問題
    {                                    //把問題拋出去
        return a/b;
    }

}

class ExceptionDemo
{
    public static void main(String[] args) throws Exception
    {
        Demo d = new Demo();

        int x = d.div(4,0);
        System.out.println("x="+x);

        System.out.println("over");
    }
}

這裏寫圖片描述

要麼try,catch處理

class Demo
{
    int div(int a,int b) throws Exception//在功能上通過throws的關鍵字聲明瞭
                                         //該功能可能會有的問題
    {                                    //把問題拋出去
        return a/b;
    }

}

class ExceptionDemo
{
    public static void main(String[] args)
    {
        Demo d = new Demo();
        try
        {
            int x = d.div(4,0);
            System.out.println("x="+x);

        }
        catch(Exception e)//Exception e = new ArithemeticException();
        {
            System.out.println("feifa");

            System.out.println(e.toString());//異常名稱:異常信息

        }
        System.out.println("over");
    }
}

這裏寫圖片描述

對多異常的處理
1,聲明異常時,建議聲明更爲具體的異常,這樣處理的更具體。
2,對方聲明幾個異常,就對應有幾個catch塊,不要定義多餘的catch塊
如果多個catch塊中的異常出現繼承關係,父類異常catch塊放在最下面

建議在進行catch處理時,catch中一定要定義具體處理方式。
不要簡單定義一句e.printStackTrace(),
也不要簡單的書寫一條輸出語句。

自定義異常

因爲項目中會出現特有的問題,
而這些問題並未被java所描述並封裝對象
所以對於這些特有的問題可以按照java的對問題封裝的思想
將特有的問題,進行自定義的異常封裝。

自定義異常

需求:在本程序中,對於除數是負數,也認爲是錯誤的,是無法進行運算的
那麼就需要對這個問題進行自定的描述

當在函數內部出現throw拋出異常對象,那麼就必須要給對應的處理動作。
要麼在內部try catch處理
要麼在函數上聲明讓調用者處理。

一般情況下,函數內出現異常,函數上需要聲明。

class FuShuException extends Exception
{
}

class Demo
{
    int div(int a,int b)throws FuShuException
    {
        if(b<0)
            throw new FuShuException();//手動通過throw關鍵字拋出一個自定義異常對象。

        return a/b;
    }
}

class ExceptionDemo3
{
    public static void main(String[] args)
    {
        Demo d = new Demo();

        try
        {
            int x = d.div(4,-1);
            System.out.println("x="+x);
        }

        catch (FuShuException e)
        {
            System.out.println(e.toString());
            System.out.println("除數是負數");


        }


        System.out.println("over");
    }
}

這裏寫圖片描述

發現打印的結果中只有異常的名稱,沒有異常的信息
因爲自定義的異常並未定義信息

如何定義異常信息呢?

因爲父類中已經把異常信息的操作都完成了。
所以子類只要在構造時,將異常信息傳遞給父類通過super語句
那麼就可以直接通過getMessage方法獲取自定義的異常信息

class FuShuException extends Exception 
{
    private int value;

    FuShuException(String msg,int value)
    {
        super(msg);
        this.value = value;
    }
    public int getValue()
    {
        return value;
    }
}

class Demo
{
    int div(int a,int b)throws FuShuException
    {
        if(b<0)
            throw new FuShuException("/ by fushu",b);//手動通過throw關鍵字拋出一個自定義異常對象。

        return a/b;
    }
}

class ExceptionDemo3
{
    public static void main(String[] args)
    {
        Demo d = new Demo();

        try
        {
            int x = d.div(4,-1);
            System.out.println("x="+x);
        }

        catch (FuShuException e)
        {
            System.out.println(e.toString());

            System.out.println("錯誤的負數是:"+e.getValue());

        }

        System.out.println("over");
    }
}

這裏寫圖片描述

自定義異常:必須是自定義類繼承Exception

繼承Exception原因
異常體系有一個特點:因爲異常類和異常對象都被拋出
他們都具備可拋性。這個可拋性是Throwable這個體系的獨有特點。

只有這個體系中的類和對象纔可以被throws和throw操作。

throws和throw的區別
throws使用在函數上
throw使用在函數內

throws後面跟的是異常類,可以跟多個,用逗號隔開
throw後面跟的是異常對象。
——————————————————————————————
Exception中有一個特殊的子類異常RunTimeException(運行時異常)

特殊之處:
如果在函數內容拋出該異常,函數上可以不聲明,編譯一樣通過
如果在函數上聲明該異常,調用者可以不用進行處理,編譯一樣通過。

之所以不用在函數上聲明,是因爲不需要讓調用者處理
當該異常發生,希望該程序停止,因爲在運行時,出現了無法繼續運算的情況,希望停止程序後,
對代碼進行修正。

自定義異常時:如果該異常的發生,無法在繼續進行運算
就讓自定義異常繼承RuntimeException

對於異常分兩種,
1,編譯時被檢測的異常

2,編譯時不被檢測的異常(運行時異常。RuntimeException以及其子類)

class FuShuException extends RuntimeException
{
    FuShuException(String msg)
    {
        super(msg);
    }
}

class Demo
{
    int div(int a,int b) //throws ArithmeticException
    {
        if(b<0)
            throw new FuShuException("出現了除數爲負數了");
        if(b==0)
            throw new ArithmeticException("被零除了");
        return a/b;
    }
}

class ExceptionDemo4
{
    public static void main(String[] args)
    {
        Demo d = new Demo();

        int x = d.div(4,-9);
        System.out.println("x="+x);

        System.out.println("over");
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章