java深入學習(二)

  1. 爲什麼匿名內部類和局部內部類只能訪問final變量?

    是變量的作用域的問題,因爲匿名內部類是出現在一個方法的內部的,如果它要訪問這個方法的參數或者方法中定義的變量,則這些參數和變量必須被修飾爲final。因爲雖然匿名內部類在方法的內部,但實際編譯的時候,內部類編譯成Outer.Inner,這說明內部類所處的位置和外部類中的方法處在同一個等級上,外部類中的方法中的變量或參數只是方法的局部變量,這些變量或參數的作用域只在這個方法內部有效。因爲編譯的時候內部類和方法在同一級別上,所以方法中的變量或參數只有爲final,內部類纔可以引用。

    簡單的來說是作用域的問題。就好像方法外面做的事情並不能改變方法內才定義的變量,因爲你並不知道方法裏面這個時候已經存在了這個局部變量了沒有。在這個內部類中方法裏面的本地變量是失效的,也就是不在作用域內,所以是不能夠訪問的

    但是爲什麼這裏用final卻又可以訪問呢?
    因爲Java採用了一種copy local variable的方式來實現,也就是說把定義爲final的局部變量拷貝過來用,而引用的也可以拿過來用,只是不能重新賦值。從而造成了可以access local variable的假象,而這個時候由於不能重新賦值,所以一般不會造成不可預料的事情發生

  2. JVM

    java -classpath . HelloWorld   
    HelloWorld  
    

    java命令首先啓動虛擬機進程(java程序),虛擬機進程成功啓動後,讀取參數“HelloWorld”,把他作爲初始類加載到內存,對這個類進行初始化和動態鏈接(關於類的初始化和動態鏈接會在後面的博客中介紹),然後從這個類的main方法開始執行。也就是說我們的.class文件不是直接被系統加載後直接在cpu上執行的,而是被一個叫做虛擬機的進程託管的。首先必須虛擬機進程啓動就緒,然後由虛擬機中的類加載器(ClassLoader)加載必要的class文件,包括jdk中的基礎類(如String和Object等),然後由虛擬機進程解釋class字節碼指令,把這些字節碼指令翻譯成本機cpu能夠識別的指令,才能在cpu上運行。

    從這個層面上來看,在執行一個所謂的java程序的時候,真真正正在執行的是一個叫做Java虛擬機的進程,而不是我們寫的一個個的class文件。這個叫做虛擬機的進程處理一些底層的操作,比如內存的分配和釋放等等。我們編寫的class文件只是虛擬機進程執行時需要的“原料”。這些“原料”在運行時被加載到虛擬機中,被虛擬機解釋執行,以控制虛擬機實現我們java代碼中所定義的一些相對高層的操作,比如創建一個文件等,可以將class文件中的信息看做對虛擬機的控制信息,也就是一種虛擬指令。

    我們編譯之後的class文件是作爲Java虛擬機的原料被輸入到Java虛擬機的內部的,那麼具體由誰來做這一部分工作呢?其實在Java虛擬機內部,有一個叫做類加載器的子系統,這個子系統用來在運行時根據需要加載類。注意上面一句話中的“根據需要”四個字。在Java虛擬機執行過程中,只有他需要一個類的時候,纔會調用類加載器來加載這個類,並不會在開始運行時加載所有的類。就像一個人,只有餓的時候纔去吃飯,而不是一次把一年的飯都吃到肚子裏。一般來說,虛擬機加載類的時機,在第一次使用一個新的類的時候。本專欄後面的文章會具體討論Java中的類加載器。

    由虛擬機加載的類,被加載到Java虛擬機內存中之後,虛擬機會讀取並執行它裏面存在的字節碼指令。虛擬機中執行字節碼指令的部分叫做執行引擎。就像一個人,不是把飯吃下去就完事了,還要進行消化,執行引擎就相當於人的腸胃系統。在執行的過程中還會把各個class文件動態的連接起來。關於執行引擎的具體行爲和動態鏈接相關的內容也會在本專欄後續的文章中進行討論。

    我們知道,Java虛擬機會進行自動內存管理。具體說來就是自動釋放沒有用的對象,而不需要程序員編寫代碼來釋放分配的內存。這部分工作由垃圾收集子系統負責。

    從上面的論述可以知道, 一個Java虛擬機實例在運行過程中有三個子系統來保障它的正常運行,分別是類加載器子系統, 執行引擎子系統和垃圾收集子系統。 如下圖所示:

    最後做一個總結:
    1 虛擬機並不神祕,在操作系統的角度看來,它只是一個普通進程。
    2 這個叫做虛擬機的進程比較特殊,它能夠加載我們編寫的class文件。如果把JVM比作一個人,那麼class文件就是我們吃的食物。
    3 加載class文件的是一個叫做類加載器的子系統。就好比我們的嘴巴,把食物吃到肚子裏。
    4 虛擬機中的執行引擎用來執行class文件中的字節碼指令。就好比我們的腸胃,對吃進去的食物進行消化。
    5 虛擬機在執行過程中,要分配內存創建對象。當這些對象過時無用了,必須要自動清理這些無用的對象。清理對象回收內存的任務由垃圾收集器負責。就好比人吃進去的食物,在消化之後,必須把廢物排出體外,騰出空間可以在下次餓的時候吃飯並消化食物。

發佈了17 篇原創文章 · 獲贊 11 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章