日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

包含内部类的.java文件编译后生成几个.class文件

發(fā)布時間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 包含内部类的.java文件编译后生成几个.class文件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如果一個類有內(nèi)部類,編譯將生成幾個字節(jié)碼文件,規(guī)則是怎樣呢?

寫在前,自己動手豐衣足食,結(jié)論只有個人實驗支持,沒有官方數(shù)據(jù)支持,歡迎自行查閱文檔然后來指正,輕噴,謝謝。

1.普通類包含內(nèi)部類的樣例

public class Test319 {private static class StaticInner{ }//靜態(tài)內(nèi)部類private class Inner{}//成員內(nèi)部類public void outerFunction1(){class PartInner3{}//局部內(nèi)部類3}public void outerFunction2(){class PartInner1{}//局部內(nèi)部類1class PartInner2{}//局部內(nèi)部類2}public Thread thread1 = new Thread(new Runnable() {//匿名內(nèi)部類1@Overridepublic void run() {}}, "thread1");public Thread thread2 = new Thread(new Runnable() {//匿名內(nèi)部類2@Overridepublic void run() {}}, "thread2");public Thread thread3 = new Thread(()->{//匿名內(nèi)部類(使用lambda表達(dá)式)},"thread3"); }

2.編譯后生成的文件目錄

3.小總結(jié)

首先,包括外部類在內(nèi)一共有9個類,而目錄中只有8個class文件,可以看出一套規(guī)律:全部內(nèi)部類編譯后都會生成字節(jié)碼文件,但是匿名內(nèi)部類有個特點
1.成員內(nèi)部類:外部類名后加一個dollar接內(nèi)部類名
2.靜態(tài)內(nèi)部類:和成員內(nèi)部類一樣(畢竟都是外部類的成員,靜態(tài)非靜態(tài)而已)
3.局部內(nèi)部類:在dollar后比成員內(nèi)部類多了個數(shù)字
4.匿名內(nèi)部類:dollar后只有一個數(shù)字,如果使用lambda表達(dá)式創(chuàng)建匿名內(nèi)部類將不生成class文件,否則會生成
其次,局部內(nèi)部類和不使用lambda表達(dá)式創(chuàng)建的匿名內(nèi)部類,他們的class文件名都包含數(shù)字,數(shù)字究竟是什么含義?(在沒有查資料的情況下,首先猜測,數(shù)字順序就是內(nèi)部類聲明的順序)先用兩個匿名內(nèi)部類來進(jìn)行測試,后面再說局部內(nèi)部類的問題。

4.關(guān)于文件名中數(shù)字的測試(匿名內(nèi)部類)

第一步,為了觀察方便給代碼做些調(diào)整,加入簡單的方法體。

public Thread thread1 = new Thread(new Runnable() {//匿名內(nèi)部類1@Overridepublic void run() {System.out.println("Hello World");}}, "thread1");public Thread thread2 = new Thread(new Runnable() {//匿名內(nèi)部類2@Overridepublic void run() {int i = 10;i += 1;}}, "thread2");

先聲明的進(jìn)行print操作,后聲明的進(jìn)行int加法計算。通過javap命令對兩個字節(jié)碼進(jìn)行解釋,結(jié)果如下:


由上述過程可看出,小數(shù)字的進(jìn)行了print,大數(shù)字的進(jìn)行了int+1,而定義的順序也就是print操作的在前,int+1操作的在后。
第二步,使用相同手法,在.java文件中調(diào)換兩個操作的聲明順序,即先聲明的進(jìn)行int+1操作,后聲明的進(jìn)行print操作,得到了相同的結(jié)論,具體不再贅述。
通過反復(fù)實驗,結(jié)果一致。但因為沒有查閱官方文檔,先提出一個我自己的想法:數(shù)字順序是內(nèi)部類的聲明順序,同時作為區(qū)分匿名內(nèi)部類的依據(jù)

5.關(guān)于局部內(nèi)部類

再回過頭說局部內(nèi)部類的問題。匿名內(nèi)部類沒有名字自然需要數(shù)字區(qū)分,那么如果其他有名字的內(nèi)部類名稱重復(fù)怎么辦(此情況只能發(fā)生于局部內(nèi)部類)?同樣可以先得出一個結(jié)論,數(shù)字是區(qū)分重名局部內(nèi)部類的依據(jù)
但是我發(fā)現(xiàn)數(shù)字順序并不是聲明順序……不再贅述實驗過程,簡單來說在外部類的兩個方法里定義名稱相同的局部內(nèi)部類,調(diào)換兩個方法的聲明位置。編譯后文件目錄如下:

這里看出數(shù)字不再是聲明順序,定義了兩個局部內(nèi)部類的方法我是后聲明的,數(shù)字反而變成了1而不是2。有種被逗了的感覺。秉持著“死也不去查資料先作作看結(jié)果”的精神,實驗繼續(xù)……(*其實是我不知道該去看官方的哪個文檔,也懶得去找*)
新定義和新編譯生成的文件目錄如下:

public class Test319 {public void outerFunction1(){class PartInner1{}}public void outerFunction2(){class PartInner1{}class PartInner2{}}public void outerFunction3(){class PartInner1{}class PartInner2{}class PartInner3{}} }


差一點,我就以為數(shù)字順序是內(nèi)部類所在方法定義的逆序了。還好所做了幾組實驗,畢竟自己歸納就已經(jīng)很不科學(xué)了,更不能僅從一組實驗就得出結(jié)論。中間步驟不說了,直接來看最后一組實驗:

public class Test319 {public void outerFunction1(){class PartInner1{}}public void outerFunction3(){class PartInner1{}class PartInner2{}class PartInner3{}}public void outerFunction2(){class PartInner1{}class PartInner2{}class PartInner3{}class PartInner4{}class PartInner5{}}public void outerFunction0(){class PartInner1{}class PartInner2{}class PartInner3{}class PartInner4{}} }


具體的自行細(xì)品吧,直接說我的結(jié)論:定義內(nèi)部類個數(shù)最多的方法,它里面的內(nèi)部類生成的class文件,名稱里的數(shù)字就是最小的。

6.最終總結(jié)

大致總結(jié)在上面的【3】,再總結(jié)一下關(guān)于數(shù)字的事情。
首先關(guān)于為什么會有數(shù)字,因為匿名內(nèi)部類沒名字(廢話。。。),局部內(nèi)部類名稱可能相同,所以數(shù)字用來做不同內(nèi)部類之間的區(qū)分,這也是為什么只有他們兩個編譯出來的字節(jié)碼文件,名稱中帶有數(shù)字。
其次關(guān)于數(shù)字順序,匿名內(nèi)部類,數(shù)字順序是聲明順序;局部內(nèi)部類,定義內(nèi)部類個數(shù)最多的方法,它里面的內(nèi)部類生成的class文件,名稱里的數(shù)字就是最小的。
以上是個人實驗的結(jié)果,未查閱文檔,有一定的不可靠性。但是懶得去找和讀文檔了,歡迎指正。

總結(jié)

以上是生活随笔為你收集整理的包含内部类的.java文件编译后生成几个.class文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。