今天剛好有同學問了下Java編譯后產生的.class文件名的問題,雖然一直都在使用Java做開發,但是之前對編譯后產生的.class文件名的規范也基本沒做了解過,也真的是懺愧啊!今天無論如何都要總結下。下面是本人今天做的實驗
1、創建類ClassA,觀察產生的.class文件。目的是測試沒有任何繼承、實現類以及內部類等情況下產生的.class文件
以及命名規則
實驗結果:
從下圖可以看出,只產生了一個.class文件,文件名為
類名.class

2、創建類ClassB,
觀察產生的.class文件。目的是測試有實現接口類情況下產生的.class文件
以及命名規則
實驗結果:
從下圖可以看出,只產生了一個.class文件
,文件名為類名.class

3、創建類ClassC,
觀察產生的.class文件。目的是測試有繼承父類情況下產生的.class文件
以及命名規則
實驗結果:
從下圖可以看出,只產生了一個.class文件
,文件名為類名.class

對以上3點做個小結:
從以上3個實驗來看,編譯后產生的.class文件跟它所實現的接口、繼承的父類都沒有關系,在這些情況下,它都只產生一個.class文件,而且文件名就是類名.class
4、
創建類ClassD,定義了一個普通內部類ClassDd,
觀察產生的.class文件。目的是測試有內部類情況下產生的.class文件以及命名規則
實驗結果:
從下圖可以看出,產生了2個.class文件,ClassD.class 和 ClassD$ClassDd.class。
這說明產生的.class文件與內部類有關系。外部類產生的文件跟上面的3個實驗結果一樣,都是類名.class,而內部類,則采用了
外部類名$內部類名.class,外部類和內部類名使用符號$隔開
注意:這里的外部類都是相對而言

5、
創建類ClassD,
定義了一個普通內部類ClassDd,再在
ClassDd定義它的內部類
ClassDdd,
觀察產生的.class文件。
目的是測試有內部類情況下產生的.class文件以及命名規則
實驗結果:
從下圖可以看出,產生了3個.class文件,ClassD.class 、 ClassD$ClassDd.class
、 ClassD$ClassDd.class
$ClassDdd.class
。
這個實驗結果跟上面的第四個實驗是一樣的,只是這次的第2層內部類文件是在第1層內部類的基礎上增加自己的類名。
注意:這里的外部類都是相對而言

對第4和第5個實驗做下小結。
以上這兩點都是驗證有普通內部類情況下產生哪些.class文件以及命名規則如何。最后得出結論如下:
類個數:看定義類的個數,包括外部類和普通的內部類
.class文件名的命名規則:外部類名 + $ + 內部類名 + .class,即等於當層內部類以及每一層外部類的名字疊加,但是每個類之間使用符號$隔開
6、
創建類ClassE,定義了一個匿名內部類,
觀察產生的.class文件。目的是測試有匿名內部類情況下產生的.class文件以及命名規則
實驗結果:
從下圖可以看出,產生了2個.class文件,ClassE.class 和 ClassE$1.class。
其實這個實驗結果跟第4個實驗的結果相似,不同的是,內部類由於沒有名字,因此采用數字來表示。這數字按照定義的匿名內部類的順序來一次增加的。


7、創建類ClassF,並在同一個.java文件中定義另外一個類ClassFf
,
觀察產生的.class文件。
目的是同一個.java文件定義的類所產生的.class文件情況
實驗結果:
同一個.java文件定義的類所產生的.class文件情況,符合上面上面驗證的規范。

最后總結:
1、編譯后產生的.class文件個數:有多少個類,產生多少個.class文件
2、
.class文件命名規則:
2.1普通內部類
外部類名 + $ + 內部類名
[
+
$ + 內部類
名
+ ...]+
.class,類名之間使用符號$隔開
例如:ClassD
$ClassDd
$ClassDdd.class,這里
ClassDdd是對底層的普通內部類,它的父類
ClassDd,而
ClassDd的父類也是最外層的外部類
ClassD
2.2匿名內部類
外部類名 + $ + 數字
[
+
$ + 數字
+ ...]+
.class,類名之間使用符號$隔開,數字根據在外部類中定義的順序決定
例如:ClassE$1$1.class
3、同一個.java文件中定義的其他非public聲明的類,都遵循以上2點規范
3、繼承、或者接口實現,不影響編譯產生的.class文件個數和命名規則