<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 312, 文章 - 14, 評論 - 1393, 引用 - 0
    數據加載中……

    java.lang.Object是如何成為默認父類的

    本文為原創,如需轉載,請注明作者和出處,謝謝!

    經常有
    Java初學者會問為什么一個沒有父類的Java類會自動從java.lang.Object類繼承。如下面是一個普通的Java類:

    public class Test    // 從Object類繼承
    {
        
    public static void main(String[] args)
        {
            System.out.println(
    new Test().toString());
        }
    }

    從上面的代碼可以看出,實際上,Test類的父類就是Object,因此,在Test中可以使用Object類的publicprotected資源,如toString方法。那么Java編譯器和JVM到底是如何做的呢?

    了解這個原因其實并不需要知道JVM的實現細節。只要思考一下對于這種虛擬機程序的原理即可。一般對于這種靠虛擬機運行的語言(如JavaC#等)會有兩種方法處理默認繼承問題。

    1. 在編譯源代碼時,當遇到沒有父類的類時,編譯器會將其指定一個默認的父類(一般為Object),而虛擬機在處理到這個類時,由于這個類已經有一個默認的父類了,因此,VM仍然會按著常規的方法來處理每一個類。對于這種情況,從編譯后的二進制角度來看,所有的類都會有一個父類。

    2. 編譯器仍然按著實際代碼進行編譯,并不會做額外的處理。如果一個類沒有顯式地繼承于其他的類,編譯后的代碼仍然沒有父類。然后由虛擬機運行二進制代碼時,當遇到沒有父類的類時,就會自動將這個類看成是Object類的子類(一般這類語言的默認父類都是Object)。

    從上面兩種情況可以看出,第1種情況是在編譯器上做的文章,也就是說,當沒有父類時,由編譯器在編譯時自動為其指定一個父類。第2種情況是在虛擬機上做文章,也就是這個默認的父類是由虛擬機來添加的。那么Java是屬性哪一種情況呢?其實這個答案很好得出。只需要隨便找一個反編譯工具,并.class文件進行反編譯即可得知編譯器是如何編譯的。就以上面代碼為例,如果是第1種情況,就算Test沒有父類,但由于編譯器已經為Test自動添加了一個Object父類,因此,在反編譯后得到的源代碼中的Test類是從Object類繼承的。如果沒是這種情況,那么就是第2種情況。

    現在我們使用JDK帶的反編譯工具javap來反編譯Test.class,先執行下面的命令:

    javap Test > Test.txt

    打開Test.txt文件后,會看到如下的代碼:

    public class Test extends java.lang.Object{
        
    public Test();
        
    public static void main(java.lang.String[]);
    }

    再使用下面的命令來得到bytecode代碼:

    javap -c Test >Test1.txt

    打開Test1.txt后,會看到如下的代碼:

    public class Test extends java.lang.Object{
    public Test();
      Code:
       
    0:    aload_0
       
    1:    invokespecial    #8//Method java/lang/Object."<init>":()V
       4:    return

    public static void main(java.lang.String[]);
      Code:
       
    0:    getstatic    #16//Field java/lang/System.out:Ljava/io/PrintStream;
       3:    new    #1//class Test
       6:    dup
       
    7:    invokespecial    #22//Method "<init>":()V
       10:    invokevirtual    #23//Method java/lang/Object.toString:()Ljava/lang/String;
       13:    invokevirtual    #27//Method java/io/PrintStream.println:(Ljava/lang/String;)V
       16:    return
    }

        從上面兩段代碼可以看出,Test已經從Object繼承了,因此,可以斷定Java是屬性第1種情況,也就是說由編譯器為沒有父類的類指定了Object作為其默認父類。如果讀者還不確定,可以直接打開Test.class,看看里面有沒有Object,圖1Test.class的十六進制代碼:



                                                    圖1

       大家可以看到,Java編譯器已經為Test指定了一個默認的Object類作為其父類。目前大多數基于虛擬器的語言都是采用的第1種方法來處理默認父類的,如下面的C#代碼:

    using System;

    namespace ConsoleApplication1
    {
        class Test
        {
           
    static void Main(string[] args)
            {
                Console.WriteLine(
    new Test().ToString());
            }
        }
    }

     使用ildasm.exe將上面的代碼反編譯后,得到的MSIL代碼如下:

    .class private auto ansi beforefieldinit ConsoleApplication1.Test
           extends [mscorlib]System.Object
    {
    // end of class ConsoleApplication1.Test

        從上面的代碼可以清楚地看到,Test類已經有一個System.Object作為父類了。






    Android開發完全講義(第2版)(本書版權已輸出到臺灣)

    http://product.dangdang.com/product.aspx?product_id=22741502



    Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


    新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

    posted on 2008-05-06 15:14 銀河使者 閱讀(2772) 評論(0)  編輯  收藏 所屬分類: java 原創

    主站蜘蛛池模板: 777亚洲精品乱码久久久久久 | 永久免费av无码网站yy| 日本xxxx色视频在线观看免费| 免费夜色污私人影院在线观看| 亚洲欧美在线x视频| 国产一区二区三区在线免费观看 | 九月丁香婷婷亚洲综合色| 182tv免费视频在线观看| 亚洲黄色片在线观看| 久久这里只有精品国产免费10| 亚洲AV日韩AV永久无码色欲 | 亚洲精品不卡视频| 影音先锋在线免费观看| 日韩精品视频在线观看免费| 久久亚洲2019中文字幕| 麻豆成人久久精品二区三区免费| 亚洲 欧洲 日韩 综合在线| 四虎影在线永久免费四虎地址8848aa | 国内精品免费在线观看| 亚洲综合激情九月婷婷| 国产一级淫片免费播放电影| 99久久免费国产精精品| 国产成人亚洲合集青青草原精品 | 国产又粗又猛又爽又黄的免费视频| 亚洲午夜在线播放| 四虎免费在线观看| 精品国产污污免费网站入口在线| 亚洲福利秒拍一区二区| 四虎永久免费影院| 久久w5ww成w人免费| 国产在亚洲线视频观看| 亚洲视频免费在线播放| 日韩视频在线精品视频免费观看| 亚洲AV无码一区二区三区性色 | 亚洲福利视频一区二区| 免费女人高潮流视频在线观看| 黄页网站在线免费观看| 97久久国产亚洲精品超碰热| 亚洲综合熟女久久久30p| 免费看国产精品麻豆| 日本免费人成黄页在线观看视频|