今天刷題的時候遇到了一題關於內部類的訪問的問題,發現本身忘了許多,如今來複習一下。
首先,內部類的類字節碼文件名字爲Outer$Inner.class。code
記住一下訪問原則:
1.內部類至關於外部類的一個成員變量,所以內部類能夠直接訪問外部類的成員。可是注意內部類靜態方法不能訪問外部類非靜態成員
2.可是外部類若是要訪問內部類中的成員,要麼內部類是靜態的,跟着外部類一塊兒被加載;要麼建立內部類的對象,經過對象訪問(想讓外部類進內部類裏面,總得有內部類的「實體」吧,這個「實體」要麼是跟外部類一塊兒加載的靜態內部類,要麼是新建的內部類的對象,不管是哪一種,都會在堆中爲內部類開闢空間,而後才能夠訪問到)
例子:對象
a.外部類訪問靜態內部類的靜態成員(一路暢通無阻) Outer.Inner.func(); b.外部類訪問靜態內部類的非靜態成員(一路暢通到內部類門口, 發現裏面還沒東西,怎麼辦?建立對象!) //通常方式 Outer.Inner in = new Outer.Inner(); in.func(); //匿名方式 new Outer.Inner().func();//new Outer.Inner()建立出對象,而後調用對象的func c.外部類訪問非靜態內部類的非靜態成員(沒對象,內部類的門都找不到!乖乖一步步建立對象吧) //通常方式 Outer.Inner in = new Outer().new Inner(); in.func(); //匿名方式 new Outer().new Inner().func();
3.內部類若是有靜態成員,則內部類也必須是靜態的(不然內部類成員要隨着外部類加載,發現內部類本身都還沒加載,那這個成員是哪兒跑出來的呢?)
4.內部類訪問局部變量時,局部變量必須加final修飾符。(隨着方法運行完畢,局部變量會被釋放,若是此時一個內部類還引用該變量則會報錯。說到底就是變量的生命週期比內部類實例要短。而final保證這個變量始終指向一個對象,內部類就能夠放心大膽地引用了。其實犯了和C++同樣的毛病:返回了局部變量的引用)
注意:在JDK8版本之中,方法內部類中調用方法中的局部變量,能夠不須要修飾爲 final,匿名內部類也是同樣的,主要是JDK8以後增長了 Effectively final 功能生命週期
class Outer{ public static void main(String[] args){ Object obj = new Outer().method(); } Object method(){ int locvar = 1; class Inner{ void displayLocvar(){ System.out.println("locvar = " + locvar); } } Object in = new Inner(); return in;//返回了內部類對象,可是該對象依然引用着局部變量 }
}class