1. 程式人生 > >java中內部類的訪問呼叫

java中內部類的訪問呼叫

從Java1.1開始引入了內部類以來,它就引起了人們的激烈爭論。其實任何優秀的語言特性用得不好就是濫用,內部類用得不好就會導致程式碼像迷宮一樣,導致出現毫無重用的綜合徵。

1、內部類分為成員內部類、靜態巢狀類、方法內部類、匿名內部類。
幾種內部類的共性:
A、內部類仍然是一個獨立的類,在編譯之後會內部類會被編譯成獨立的.class檔案,但是前面冠以外部類的類命和$符號。
B、內部類不能用普通的方式訪問。內部類是外部類的一個成員,因此內部類可以自由地訪問外部類的成員變數,無論是否是private的。

2、成員內部類:形式如下
    class Outer {
        class Inner{}
    }       

編譯上述程式碼會產生兩個檔案:Outer.class和Outer$Inner.class。
成員內部類內不允許有任何靜態宣告!下面程式碼不能通過編譯。
    class Inner{
        static int a = 10;
    } 
能夠訪問成員內部類的唯一途徑就是通過外部類的物件!

A、從外部類的非靜態方法中例項化內部類物件。

class Outer {
        
privateint i =10;
        
publicvoid makeInner(){
            Inner in 
=new Inner();
            in.seeOuter();
        }
        
class Inner{
            
publicvoid seeOuter(){
                System.out.print(i);
            }
        }
    }

表面上,我們並沒有建立外部類的物件就例項化了內部類物件,和上面的話矛盾。事實上,如果不建立外部類物件也就不可能呼叫makeInner()方法,所以到頭來還是要建立外部類物件的。
你可能試圖把makeInner()方法修飾為靜態方法,即static public void makeInner()。這樣不建立外部類就可以例項化外部類了!但是在一個靜態方法裡能訪問非靜態成員和方法嗎?顯然不能。它沒有this引用。沒能跳出那條規則!但是如果在這個靜態方法中例項化一個外部類物件,再用這個物件例項化外部類呢?完全可以!也就是下一條的內容。


B、從外部類的靜態方法中例項化內部類物件。
    class Outer {
        private int i = 10;
        class Inner{
            public void seeOuter(){
                System.out.print(i);
            }
        }    
        public static void main(String[] args) {
            Outer out = new Outer();
            Outer.Inner in = out.new Inner();
            //Outer.Inner in = new Outer().new Inner();
            in.seeOuter();
        }
    }

被註釋掉的那行是它上面兩行的合併形式,一條簡潔的語句。
對比一下:在外部類的非靜態方法中例項化內部類物件是普通的new方式:Inner in = new Inner();
在外部類的靜態方法中例項化內部類物件,必須先建立外部類物件:Outer.Inner in = new Outer().new Inner();

C、內部類的this引用。
普通的類可以用this引用當前的物件,內部類也是如此。但是假若內部類想引用外部類當前的物件呢?用“外部類名”.this;的形式,如下例的Outer.this。
    class Outer {
        class Inner{
            public void seeOuter(){
                System.out.println(this);
                System.out.println(Outer.this);
            }
        }
    }

D、成員內部類的修飾符。
對於普通的類,可用的修飾符有final、abstract、strictfp、public和預設的包訪問。
但是成員內部類更像一個成員變數和方法。
可用的修飾符有:final、abstract、public、private、protected、strictfp和static。
一旦用static修飾內部類,它就變成靜態內部類了。


3、方法內部類。
顧名思義,把類放在方法內。
    class Outer {
        public void doSomething(){
            class Inner{
                public void seeOuter(){
                }
            }    
        }
    }
A、方法內部類只能在定義該內部類的方法內例項化,不可以在此方法外對其例項化。

B、方法內部類物件不能使用該內部類所在方法的非final區域性變數。
因為方法的區域性變數位於棧上,只存在於該方法的生命期內。當一個方法結束,其棧結構被刪除,區域性變數成為歷史。但是該方法結束之後,在方法內建立的內部類物件可能仍然存在於堆中!例如,如果對它的引用被傳遞到其他某些程式碼,並存儲在一個成員變數內。正因為不能保證區域性變數的存活期和方法內部類物件的一樣長,所以內部類物件不能使用它們。
下面是完整的例子:
    class Outer {
        public void doSomething(){
            final int a =10;
            class Inner{
                public void seeOuter(){
                    System.out.println(a);
                }
            }   
            Inner in = new Inner();
            in.seeOuter(); 
        }
        public static void main(String[] args) {
            Outer out = new Outer();
            out.doSomething();
        }
     }

C、方法內部類的修飾符。
與成員內部類不同,方法內部類更像一個區域性變數。
可以用於修飾方法內部類的只有final和abstract。

D、靜態方法內的方法內部類。
靜態方法是沒有this引用的,因此在靜態方法內的內部類遭受同樣的待遇,即:只能訪問外部類的靜態成員。


4、匿名內部類。
顧名思義,沒有名字的內部類。表面上看起來它們似乎有名字,實際那不是它們的名字。

A、繼承式的匿名內部類。
    class Car {
        public void drive(){
            System.out.println("Driving a car!");
        }
    }

    class Test{
        public static void main(String[] args) {
            Car car = new Car(){
                public void drive(){
                    System.out.println("Driving another car!");
                }
            };
            car.drive();
        }
    }
結果輸出了:Driving another car! Car引用變數不是引用Car物件,而是Car匿名子類的物件。
建立匿名內部類的關鍵點是重寫父類的一個或多個方法。再強調一下,是重寫父類的方法,而不是建立新的方法。因為用父類的引用不可能呼叫父類本身沒有的方法!建立新的方法是多餘的。簡言之,參考多型。

B、介面式的匿名內部類。
    interface  Vehicle {
        public void drive();
    }

    class Test{
        public static void main(String[] args) {
            Vehicle v = new Vehicle(){
                public void drive(){
                    System.out.println("Driving a car!");
                }
            };
            v.drive();
        }
    }
上面的程式碼很怪,好像是在例項化一個介面。事實並非如此,介面式的匿名內部類是實現了一個介面的匿名類。而且只能實現一個介面。

C、引數式的匿名內部類。
class Bar{
    void doStuff(Foo f){}
}

interface Foo{
    void foo();
}

class Test{
    static void go(){
        Bar b = new Bar();
        b.doStuff(new Foo(){
            public void foo(){
                System.out.println("foofy");
            }
        });
    }
}


5、靜態巢狀類。
從技術上講,靜態巢狀類不屬於內部類。因為內部類與外部類共享一種特殊關係,更確切地說是對例項的共享關係。而靜態巢狀類則沒有上述關係。它只是位置在另一個類的內部,因此也被稱為頂級巢狀類。
靜態的含義是該內部類可以像其他靜態成員一樣,沒有外部類物件時,也能夠訪問它。靜態巢狀類不能訪問外部類的成員和方法。
    class Outer{
        static class Inner{}
    }
    class Test {
        public static void main(String[] args){
            Outer.Inner n = new Outer.Inner();

相關推薦

java部類訪問區域性變數為什麼要定義區域性變數為final

因為方法內定義的變數是區域性變數,離開該方法,變數就失去了作用,也就會自動被消除,而內部類卻不會離開它所在方法就失去作用,它有更廣的生命週期,下面通過一個例項加以說明: 如例中所示,在外部類Outer中聲明瞭一個內部類TimerPrint,這個類中的方法引用了方法start

java部類訪問呼叫

從Java1.1開始引入了內部類以來,它就引起了人們的激烈爭論。其實任何優秀的語言特性用得不好就是濫用,內部類用得不好就會導致程式碼像迷宮一樣,導致出現毫無重用的綜合徵。1、內部類分為成員內部類、靜態巢狀類、方法內部類、匿名內部類。幾種內部類的共性:A、內部類仍然是一個獨立

java部類的建立四種情況,三種方式,及內部資料訪問許可權

內部類和外部類的關係,及內部靜態類的資料訪問許可權,宣告方式。 第一種,在外部類內部宣告使用內部類,內部類的型別為static和非 static型別,內部類資料型別為private,protected,public 型別的訪問許可權。外部類為非靜態宣告和許可權如下: p

java部類在區域性時,訪問許可權》

/* 內部類定義在區域性時, 1,不可以被成員修飾符修飾 2,可以直接訪問外部類中的成員,因為還持有外部類中的引用。 但是不可以訪問它所在的區域性中的變數。只能訪問被final修飾的區域性變數。 *

Java 部類特性總結(吐血之作)

內部 不能 今天 了解 基本 靜態 外部類 pro this PS:今天花了整個下午時間看內部類相關的內容,因知識點多而雜,故記之如下。 一、內部類的作用 內部類看起來是一種代碼隱藏機制:將類置於其他類的內部。它還了解外部類,並能與之通信;使用內部類可以實現閉包;內部

java部類使用小結

內部類的宣告與訪問 內部類可以是static的也可以用其它四種訪問修飾符(而外部類只能使用public和 default修飾)。內部類所能實現的功能外部類也同樣可以全部實現,只是使用內部類可以使其更加簡潔高效。 內部類是一個編譯時概念,一旦編譯成功就會變成兩個完全不同

Java部類的定義及使用

一、定義 1.在一個類的內部進行其他類結構的巢狀的操作。 例: class Outer{ private String msg = "Hello World!"; //定義一個內部類 //*********************************

JAVA部類的繼承和覆蓋問題

在JAVA中,由於內部類的構建器必須連線到指向其外圍類物件的引用,所以在繼承內部類的時候會變得很複雜。問題在於指向外圍類物件的祕密引用必須得到初始化,而在匯出類中不再存在可連線的預設物件,我們必須使用

解決JAVA部類所對應的外部類引用初始化的問題

java內部類的分類 java內部類的分類:成員內部類、區域性內部類、靜態內部類(巢狀類)、匿名內部類。 在構建內部類物件時,需要一個指向其外部類物件的引用,而且這種引用的傳遞是通過內部類的構造器來完成的。 如果編譯器訪問不到這個引用就會報錯。 CASE 1: // 用.n

JAVA部類和匿名部類的區別,分別在什麼時候使用它們?

今天沒事,抽出時間總結了一下很多開發人員都想弄明白的一些JAVA基礎知識(內部類和匿名內部類)。 一、JAVA中內部類和匿名內部類的區別          內部類:內部類可以是static的或者非static的,static內部類只能包含靜態方法和靜態類變數,只能訪問外部類的

Java 部類、靜態部類、列舉類

一、內部類 在另一個類中定義的類 內部類作用 1、內部類提供了更好的封裝。只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問。 2、內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類成員。當外部類不能訪問內部類的內部屬性。 內

Java部類的記憶體洩露問題

package com.example.temptemp; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.Text

Java部類和異常處理

1、 內部類 內部類的訪問規則: 1) 內部類可以訪問外部類的成員包括私有。 之所以可以直接訪問外部類的成員,是因為內部類持有一個外部類的引用 , 格式: 外部類名.this 2) 外部類要訪問內部類,必須建立內部類物件。 當內部類處於外

Java進階——Java 區域性部類訪問區域性變數為什麼必須加final關鍵字

Java 區域性內部類訪問區域性變數為什麼必須加final關鍵字 疑問 在Java中,區域性內部類如果呼叫了方法中的變數,那麼該變數必須申明為final型別,如果不申明,則編譯就會出錯。 這裡的內部類指的是方法內部類或匿名內部類,不包含靜態內部類和成員內部類

關於Java部類的一些概念整理

    把一個類放到另一個類的內部定義,這個定義在其他類內部的類就被稱為內部類。     內部類的作用:     (1).內部類提供了更好的封裝,可以把內部類隱藏在外部類之內,不允許同一個包中的其他類訪問該類。     (2).內部類成員可以直接訪問外部類的私有資料,因為內

java部類和異常類

這是在eclipse中建立的一個Example8_2的類,其中有些錯誤,我想在這裡註明一下。只是想以後自己看看,希望不要在出現這樣的錯誤。 package s8_2; /**  * @author Administrator  *本節主要是講內部類和異常類  */ /

Java部類的騷操作

  10.1 如何定義內部類 如程式碼10.1-1 所示 public class Parcel1 { public class Contents{ private int value = 0;​ public int getValue(){

Java部類和靜態部類的區別

內部類和靜態內部類 示例 public class OuterClass { private int numPrivate = 1; public int numPublic = 2; public static int numPublicStatic = 3; private

java:面向物件-區域性部類訪問區域性變數的問題

* 區域性內部類訪問區域性變數必須用final修飾* 區域性內部類在訪問他所在方法中的區域性變數必須用final修飾,為什麼? 因為當呼叫這個方法時,區域性變數如果沒有用final修飾,他的生命週期和方

“全棧2019”Java第七十二章:靜態部類訪問部類成員

難度 初級 學習時間 10分鐘 適合人群 零基礎 開發語言 Java 開發環境 JDK v11 IntelliJ IDEA v2018.3 文章原文連結 “全棧2019”Java第七十二章:靜態內部類訪問外部類成員 下一章 “全棧2019”Java第七十三章:外部類裡多