Java有各類各樣類,內部類、嵌套類、成員類、局部類(本地類)、靜態類、匿名類、文件類以及這些組合起來的稱呼類,成員內部類,成員匿名類,成員嵌套類,本地匿名類等,真是多的不行,但有些實際上是一個意思,在這裏好好理一理。java
1.注意,這些稱呼都是翻譯過來的,可是同一個英文單詞或一個詞組翻譯過來可能有不一樣叫法,好比local nested class,local有局部、本地意思,實際上是一個意思,local nested class翻譯過來就是局部嵌套類(本地嵌套類),又由於非靜態嵌套類都稱爲內部類,因此local nested class又叫爲內部局部類(本地內部類),最終又簡稱爲:局部類(本地類)。我我的以爲局部類更加形象點因此下面都優先採用局部類一說。
2.我經過搜索找到兩種不太相同的內部類定義,一種認爲:定義在類裏面的稱爲嵌套類(nested class),而非靜態嵌套類纔是內部類(inner class),也就是說嵌套類包含內部類;另一種則是認爲:定義在類裏面的稱爲內部類,這樣靜態嵌套類也是內部類,也就是說嵌套類=內部類。可是,第一種纔是Java語言規範規定的,我一開始不肯定,找到Java7的語言規範驗證,結果確實如此,即第一種纔是正確的,那麼問題來了:依照第一種劃分,靜態內部類實際上是一種錯誤說法。。。只有靜態嵌套類,內部類是沒有靜態一說的!
可是對於大多數中國程序員,貌似將定義在類裏面的類稱爲內部類不是更符合文意麼?也許這就是爲何會有這麼多人一直認爲靜態內部類的存在。嘛,反正無論怎麼稱呼,只要知道表明什麼意思就好,細節什麼的不要在乎(光哥:因此不注意細節的你寫的代碼才這麼一大堆bug麼?還不趕忙去改(怒吼))。
我這裏採用Java語言規範上說的。程序員
文件類放在最前面,是由於文件類是與主類(一個文件中public類)關係最不密切的一類。什麼是文件類?看代碼就知道:express
public class Main{} class Test{}//Test就是文件類 //是的,一個.java文件裏面定義在主類外面的就是文件類 //主類、文件類稱爲頂級類(top level class),Java語言規範中定義:非嵌套類即爲頂級類。
【注意】:主類這必定義是我本身按語義稱呼的,有的地方稱爲基本類,但我以爲很不符合語義,Java語言規範我也沒找到相關定義。ide
由上面文件類可有相似定義:一個.java文件裏面定義在類裏面的就是嵌套類,定義在類內部,包括塊、靜態塊、構造器、方法內。這個時候該類也相對來被稱爲包裝類(enclosing class)或外部類。
嵌套類是能夠有層次的,也就是說嵌套類裏面還能夠定義類,成爲嵌套類中的嵌套類。
在Java語言規範裏面,嵌套類定義是:spa
A nested class is any class whose declaration occurs within the body of another class or interface.
說的簡單一點,就是定義在類(這裏還包括接口,下同)裏面的類。因此說,如下全部的類均可以稱爲嵌套類。嵌套類分爲兩種:靜態嵌套類和非靜態嵌套類,非靜態嵌套類就是內部類(inner class)。.net
簡稱靜態類,和主類關係也不大,只是在其餘類中引用使用的時候須要加上外部類限定,但在技術上來看,徹底是兩個獨立無關係的類。翻譯
public class Main{ public static class NestClass{} } //在外面使用時候形式以下,在Main中使用則不須要加上外部類限定 Main.NestClass nestClass = new Main.NestClass();
從形式上來看,靜態類能夠說是類的一個靜態成員(因此也能夠說是成員類一種),但從技術上來看,其實兩者沒什麼關係,能夠看作第三類頂級類。但也所以,靜態類不怎麼經常使用,由於它同通常類沒什麼優點可言。code
Java語言規範裏的定義:對象
An inner class is a nested class that is not explicitly or implicitly declared static. //即非靜態嵌套類即爲內部類
內部類包括:成員類、局部類、匿名類。blog
public static final int a = 6;
這裏說的是非靜態成員內部類(若是靜態嵌套類也算是成員類一種的話),non-static member (inner) class。而通常說的也是這種,但從技術上來看,成員類應該還包括靜態嵌套類。
A member class is a class whose declaration is directly enclosed in another class or interface declaration.
成員類算是最多見最經常使用的一種內部類,咱們通常說的內部類說的就是成員類:在類裏面,但不在塊、構造器、方法裏面。
//成員類,從技術上來講,能夠分爲兩種:成員內部類和成員嵌套類。 //1.成員內部類即這裏說的成員類,全稱是非靜態成員內部類 //2.成員嵌套類即上面的靜態嵌套類 public class Main{ public class MemberClass{}//成員內部類,常簡稱爲成員類 }
成員類,可使用public,private,protected訪問控制符,也能夠用static,final關鍵字修飾,而且有enclose class屬性。
這裏題外說明一下:
local nested class,局部嵌套類,簡稱局部類,局部類所屬範圍:在塊、構造器以及方法內,這裏的塊包括普通塊和靜態塊。局部類只在本塊範圍內有效。
定義:
A local class is a nested class (§8) that is not a member of any class and that has a name.
翻譯過來就是:局部類是嵌套類,但不是成員類,並且有名稱(不是匿名類)。
public class Test { { class AA{}//塊內局部類 } public Test(){ class AA{}//構造器內局部類 } public static void main(String[] args){ } public void test(){ class AA{}//方法內局部類 } } //注意到了吧,能夠同名,編譯後,造成諸如:外部類名稱+$+同名順序+局部類名稱 //Test$1AA.class/Test$2AA.class/Test$3AA.class
局部類最多隻能有final修飾,但不一樣的是,塊內局部類有enclose class屬性,而構造器局部類有enclose constructor屬性,方法局部類有enclose method屬性,嘛,其實很好理解的吧,一看就知道。
定義:
An anonymous class declaration is automatically derived from a class instance creation expression by the Java compiler
匿名類,就是沒有名稱的類,其名稱由Java編譯器給出,通常是形如:外部類名稱+$+匿名類順序,沒有名稱也就是其餘地方就不能引用,不能實例化,只用一次,固然也就不能有構造器。
匿名類根據位於地方不一樣分爲:成員匿名類和局部匿名類。
public class Test { InterfaceA a = new InterfaceA() {};//成員匿名類 public static void main(String[] args){ InterfaceA a = new InterfaceA() {};//局部匿名類 //以上兩種是經過實現接口實現匿名類,稱爲接口式匿名類,也能夠經過繼承類 Test test = new Test(){};//繼承式匿名類 //還能夠是位於參數上 new Thread(new Runnable() { @Override public void run() { } }).start();//屬於局部匿名類一種 } private interface InterfaceA{} }
匿名類不能使用任何關鍵字和訪問控制符,匿名類和局部類訪問規則同樣,只不過內部類顯式的定義了一個類,而後經過new的方式建立這個局部類實例,而匿名類直接new一個類實例,沒有定義這個類。匿名類最多見的方式就是回調模式的使用,經過默認實現一個接口建立一個匿名類而後,而後new這個匿名類的實例。
本文討論的是:嵌套類、內部類、成員類、局部類、匿名類相關,這些類的劃分主要是根據類聲明(或位於)的地方劃分的: 1.嵌套類,位於類內部,又分爲:靜態嵌套類和非靜態嵌套類。 2.靜態嵌套類即爲靜態類。靜態類只有這一種,技術來講,也能夠當作靜態成員類。 3.非靜態嵌套類即爲內部類,又分爲:成員類、局部類(本地類)、匿名類。 4.成員類:位於類內部但不包括位於塊、構造器、方法內,且有名稱的類。 5.局部類:位於塊、構造器、方法內的有名稱類。 6.匿名類:類內無名稱類,又可細分爲:成員匿名類和局部匿名類。