<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 原創

    主站蜘蛛池模板: 五月天国产成人AV免费观看| 亚洲A∨午夜成人片精品网站| 国产日韩精品无码区免费专区国产 | 色网站在线免费观看| 亚洲欧洲综合在线| 亚洲国产精品SSS在线观看AV| 免费jjzz在在线播放国产| 成人免费毛片内射美女APP| 69精品免费视频| 拍拍拍无挡免费视频网站| 免费一级毛片在线播放视频免费观看永久 | 国产aa免费视频| 女人被男人桶得好爽免费视频| 99re免费在线视频| 免费91麻豆精品国产自产在线观看 | 黄色免费在线网址| 亚洲GV天堂无码男同在线观看| 亚洲成a人片在线观看精品| 亚洲精品视频免费看| 情人伊人久久综合亚洲| 国产亚洲精品福利在线无卡一| 亚洲第一永久AV网站久久精品男人的天堂AV| 黄瓜视频高清在线看免费下载| 日本成年免费网站| 免费阿v网站在线观看g| 很黄很黄的网站免费的| 97热久久免费频精品99| 国产香蕉免费精品视频| 国产男女爽爽爽爽爽免费视频| 亚洲一区免费视频| 91成人免费观看网站| 亚洲一区二区三区免费观看| 2015日韩永久免费视频播放| 免费在线观看视频网站| 思思re热免费精品视频66| 欧美男同gv免费网站观看| 成人毛片视频免费网站观看| 日本免费福利视频| 免费国产人做人视频在线观看| 亚洲av中文无码| 亚洲精品国精品久久99热一|