java編譯器和虛擬機
1、安裝JDK,配置環境變數。 不將JDK所在的目錄配置到系統環境變數中,系統怎麼能找到JDK中的編譯器,解釋器在哪呀?如果不指明JDK的bin文件夾的位置,在shell中是無法找到javac/java命令的。這點就不多說了。 2、編譯,解釋執行Java程序。【 javac命令/java命令】 (1) Test.java源代碼 Java代碼 //預設包,該程序源代所在位置: e:/project/ Test.java public class Test{ ..... public static void main(String[] args){ ..... } } 編譯命令: 【javac e:/project/Test.java 】 在e:/project目錄下生成了Test.class 注意: ① 如果想要將Test.class生成在指定目錄下,可以使用javac -d命令,如【 javac -d c:/ e:/project/Test.java 】 在c:/目錄下生成T est.class(即e:/Test.class) ② javac -cp 中的-cp並不是指定Test.java的目錄,這一點不要誤解了。-cp/-classpath只能是指定類文件(.class文件)的路徑。上面的命令不能寫成: java -cp e:/project Test.java 解釋執行命令 :【 j ava -cp e:/project Test】 將調用解釋器執行e:/project中的Test.class位元組碼。 注意: ① -cp 是指定用戶類文件的位置,比如上面的Test.class的位置。這里因為要尋找Test.class類文件,而不是Test.java源代碼文件,所以要通過-cp指定。千萬沒有這樣的執行命令: java e:/project/Test (2) Test.java源代碼 Java代碼//預設包,但源代碼中引用了一個JAR包內的自定義類,這個JAR包位於c:/目錄下 import net.single.util.SL; //導入自定義JAR包中的類 public class Test{ private SL aObject=new SL(); //初始化JAR中的SL類 public static void main(String[] args){ ...... } } 編譯命令: 【 javac -cp c:/single.jar e:/project/Test.java】 在e:/project目錄下生成了Test.class 注意: 如果當前你要編譯的java文件中引用了其它的類,但該引用類的.class文件不在當前目錄下(或在其他目錄下,或在.zip/.jar內),這種情況下就需要在javac命令後面,加上-cp/-classpath參數來指明這些類的位置。 一般來說有三種指定方式: ① 絕對或相對路徑:javac -cp c:/single.jar Test .java 或 javac -cp ../single.jar Test .java (其中.. 表示上一級目錄)
② 系統變數:javac -cp %CLASSPATH% Test .java (其中:%CLASSPATH%表示使用系統變數CLASSPATH的值進行查找,這里假設single.jar的路徑就包含在CLASSPATH系統變數中) ③ 當前目錄: javac -cp ./single.jar Test.java (其中. 表示當前目錄) 解釋執行命令 :【 java -cp c:/single.jar;e:/project Test】 注意: ① -cp的路徑不僅指定了所需要的single.jar的位置,還必須指出編譯後的Test.class的位置。 ② 類路徑中的不同項目要用分隔符區分,Unix系統的分隔符是冒號(:),Windows的是分號(;) (3) Test.java 源代碼 Java代碼//該類在net.single包中,類中沒有引入其他目錄下的自定義類 package net.single; public class Test{ ..... public static void main(String[] args){ ..... } } 編譯命令:【javac -d . e:/project/Test.java 】 注意: ① 如果沒有-d而直接編譯javac e:/project/Test.java。將會在 e:/project 目錄下直接生成一個Test.class,但此Test.class無法解釋執行,因為它實際上在e.single包中。所以必須將包一起編譯出來,這里用了-d參數。 ② 上面的編譯結果將在e:/目錄下 自動根據包的結構形式創建文件目錄,e:/net/single/Test.class 解釋執行命令 :【java -cp e:/ net.single.Test 】 現在我們總結一下: [a.] 沒有IDE環境,編譯一個大型項目是很困難的,因為必須把需要被其他類引用的類先編譯,而且最好把包結構一起編譯出來。所以一般命令格式如下: 編譯: javac -cp (需要引入的類文件路徑1;需要引入的類文件路徑2;....) -d (編譯出的類文件存放的位置目錄) (待編譯文件路徑) 執行: java -cp (需要解釋執行的類文件路徑) (帶包的類文件) 例:現在要編譯一個類源碼: Test.java,其中該類位於E:/project/下 (1. Test源代碼中使用了一個JAR包中的類,這個single.jar包位於C:/目錄下。 (2. Test源代碼中使用了一個自定義類Content,這個類的源代碼Content.java位於E:/下 (3. Test所在包為net.single,Content所在包為net.single.cont 解決: 步1:由於Test使用了Content類,所以必須先編譯Content,而且Content類在E:/目錄下,而且 屬於包net.single.cont 編譯命令: javac -d . e:/Content.java 編譯結果: 在Content.java的當前目錄下生成了一個 net/single/cont/Content.class 文件(帶包結構),即e:/net/single/cont/Content.class 步2:編譯Test類,並指明所引入的single.jar包和Content.class的位置 編譯命令: javac -cp c:/single.jar;e:/net/single/cont -d . e:/project/Test.java 編譯結果: 在Test的上一級目錄下生成了一個 net/single/Test.class 文件,即e:/ net/single/Test.class 步3:解釋執行Test.class 執行命令: java -cp c:/single.jar;e:/ net.single.Test 3、編譯器,虛擬機如何定位到類的 Java代碼package net.single; import java.util.*; import net.single.util.*; public class Test{ //SingleUtil類在c:/single.jar中的net.single.util包下 private SingleUtil sut=new SingleUtil(); } 編譯命令: javac -cp c:/single.jar -d . e:/project/Test.java 編譯器首先找到e:/project/Test.java。然後對Test源代碼進行編譯,當編譯到創建SingleUtil類對象的語句時,編譯器要開始尋找SingleUtil.class的位置。編譯器首先查找包含這個類的所有包的位置,並查詢所有的import指令,確定其中是否包含了被引用了的類。 如上面的Test.java,編譯器將試圖查找java.lang.SingleUtil,java.util.SingleUtil,net.single.util.SingleUtil以及當前包中的SingleUtil(即net.single.SingleUtil)。編譯器將在三個部分中查找類文件: (1) 在JDK的lib目錄下的標准類庫文件中查找java.lang,java.util和net.single.util包。顯然只能找到java.lang和java.util包。然後在這兩個包中查找SingleUtil類文件。當然是找不到的。 (2) 在編譯命令中-cp參數表明的類路徑(C:/single.jar)下查找java.lang,java.util和net.single.util包。顯然只能找到net.single.util包,然後在裡面找到SingleUtil類文件。 (3) 在Test.java的當前目錄下查找SingleUtil,也是沒有的。 如果沒有找到SingleUtil,或者找到多個SingleUtil。
Ⅱ java編譯器和java虛擬機的關系
java編譯器是開發java程序用的
java虛擬機是java跨平台的解釋java程序和運行java程序用的
Ⅲ java的虛擬機 編譯器 解釋器 都什麼關系啊
Java虛擬機(JVM)一種用於計算機設備的規范,可用不同的方式(軟體或硬體)加以實現。編譯虛擬機的指令集與編譯微處理器的指令集非常類似。Java虛擬機包括一套位元組碼指令集、一組寄存器、一個棧、一個垃圾回收堆和一個存儲方法域。
Java虛擬機(JVM)是可運行Java代碼的假想計算機。只要根據JVM規格描述將解釋器移植到特定的計算機上,就能保證經過編譯的任何Java代碼能夠在該系統上運行。
Java虛擬機是一個想像中的機器,在實際的計算機上通過軟體模擬來實現。Java虛擬機有自己想像中的硬體,如處理器、堆棧、寄存器等,還具有相應的指令系統。
參考:http://ke..com/view/374952.htm
Javac編譯器
Javac編譯器讀取Java源代碼,並將其編譯成位元組代碼,調用Javac的命令行示例如下:
C:>javac options filename.java
值得注重的是,和Java解釋器不同,Javac 編譯器期望它正在編譯的文件具有擴展名.java。其命令行如下表 選項 功能
-classpath path 此選項用於設定路徑,在該路徑上Javac尋找需被調用的類。該路徑是一個用分號分開的目錄列表。
-d Directory 此選項指定一個根目錄。該目錄用來創建反映軟體包繼續關系的目錄數。
-g 此選項在代碼產生器中打開調試表,以後可憑此調試產生位元組代碼。
-nowarn 此選項禁止編譯器產生警告。
-o 此選項告訴javac優化由內聯的static、final以及privite成員函數所產生的碼。
-verbose 此選項告知Java顯示出有關被編譯的源文件和任何被調用類庫的信息。
參考:http://ke..com/view/2972115.htm
Ⅳ JAVA虛擬機是什麼意思
Java虛擬機(Java Virtual Machine,簡稱JVM)是一種假想的計算機。從結構上看,它由抽象的指令集、寄存器組、類文件格式規定、堆棧、內存垃圾收集器和存儲區六個部件組成。指令集採用與平合無關的位元組碼形式,寄存器組中包含程序計數器、堆棧指針、運行環境指針和變數指針,類文件也與平台無關,堆棧用來傳遞參數和返回運行結果,垃圾收集器收集不再使用的內存片段,存儲區則用來存放位元組碼。JVM僅僅規定部件的功能和規格。雖然這些功能和規格是統一的,但是並沒有規定這此部件的具體實現技術,就是說,可以用任何一種技術來實現。
Java中引入了虛擬機的概念,即在機器和編譯程序之間加入了一層抽象的虛擬的機器。這台虛擬的機器在任何平台上都提供給編譯程序一個的共同的介面。編譯程序只需要面向虛擬機,生成虛擬機能夠理解的代碼,然後由解釋器來將虛擬機代碼轉換為特定系統的機器碼執行。在Java中,這種供虛擬機理解的代碼叫做位元組碼(ByteCode),它不面向任何特定的處理器,只面向虛擬機。
每一種平台的解釋器是不同的,但是實現的虛擬機是相同的。Java源程序經過編譯器編譯後變成位元組碼,位元組碼由虛擬機解釋執行,虛擬機將每一條要執行的位元組碼送給解釋器,解釋器將其翻譯成特定機器上的機器碼,然後在特定的機器上運行。
可以說,Java虛擬機是Java語言的基礎。它是Java技術的重要組成部分。Java虛擬機是一個抽象的計算機,和實際的計算機一樣,它具有一個指令集並使用不同的存儲區域。它負責執行指令,還要管理數據、內存和寄存器。Java解釋器負責將位元組代碼翻譯成特定機器的機器代碼。Java是一種簡單的語言。它用到的概念不多,而且多為程序員所熟悉。如果你是一名程序員,掌握Java對你來說是易如反掌的事。即使你沒有學過任何編程語言,學習Java也要比學習C++要容易的多。
Ⅳ 關於java編譯器和虛擬機的一個問題(非誠勿擾)
包定義,只是方便管理文件,,,,,,既然不按JAVA標准存放相應的JAVA源文件,那編譯時就不存放到相應的包的路徑下,,,,,,運行時就不正確。。。。
這個是源文件的管理,不是什麼地址。
依賴其它包,也要看是怎樣的依賴,如果依賴的是.jar,是不會出錯的。
~
~
~
~
~
Ⅵ 什麼是 Java 虛擬機
您好,提問者:
Java虛擬機簡稱JVM,它的作用如下:
1、其實Java不可跨平台,真正實現跨平台的是JVM虛擬機。
2、JVM其實就是一個編譯java、運行class的一個跟操作系統的一個軟體。
3、JVM的作用只針對於Java,而系統中的東西與它無關。
4、其實說白了就是一個軟體,就像VMware一樣。
Java虛擬機
一、什麼是Java虛擬機
Java虛擬機是一個想像中的機器,在實際的計算機上通過軟體模擬來實現。Java虛擬機有自己想像中的硬體,如處理器、堆棧、寄存器等,還具有相應的指令系統。
為什麼要使用Java虛擬機
Java語言的一個非常重要的特點就是與平台的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平台上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機後,Java語言在不同平台上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平台相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(位元組碼),就可以在多種平台上不加修改地運行。Java虛擬機在執行位元組碼時,把位元組碼解釋成具體平台上的機器指令執行。
2.誰需要了解Java虛擬機
Java虛擬機是Java語言底層實現的基礎,對Java語言感興趣的人都應對Java虛擬機有個大概的了解。這有助於理解Java語言的一些性質,也有助於使用Java語言。對於要在特定平台上實現Java虛擬機的軟體人員,Java語言的編譯器作者以及要用硬體晶元實現Java虛擬機的人來說,則必須深刻理解Java虛擬機的規范。另外,如果你想擴展Java語言,或是把其它語言編譯成Java語言的位元組碼,你也需要深入地了解Java虛擬機。
3.Java虛擬機支持的數據類型
Java虛擬機支持Java語言的基本數據類型如下:
byte://1位元組有符號整數的補碼
short://2位元組有符號整數的補碼
int://4位元組有符號整數的補碼
long://8位元組有符號整數的補碼
float://4位元組IEEE754單精度浮點數
double://8位元組IEEE754雙精度浮點數
char://2位元組無符號Unicode字元
幾乎所有的Java類型檢查都是在編譯時完成的。上面列出的原始數據類型的數據在Java執行時不需要用硬體標記。操作這些原始數據類型數據的位元組碼(指令)本身就已經指出了操作數的數據類型,例如iadd、ladd、fadd和dadd指令都是把兩個數相加,其操作數類型別是int、long、float和double。虛擬機沒有給boolean(布爾)類型設置單獨的指令。boolean型的數據是由integer指令,包括integer返回來處理的。boolean型的數組則是用byte數組來處理的。虛擬機使用IEEE754格式的浮點數。不支持IEEE格式的較舊的計算機,在運行Java數值計算程序時,可能會非常慢。
虛擬機支持的其它數據類型包括:
object//對一個Javaobject(對象)的4位元組引用
returnAddress//4位元組,用於jsr/ret/jsr-w/ret-w指令
注:Java數組被當作object處理。
虛擬機的規范對於object內部的結構沒有任何特殊的要求。在Sun公司的實現中,對object的引用是一個句柄,其中包含一對指針:一個指針指向該object的方法表,另一個指向該object的數據。用Java虛擬機的位元組碼表示的程序應該遵守類型規定。Java虛擬機的實現應拒絕執行違反了類型規定的位元組碼程序。Java虛擬機由於位元組碼定義的限制似乎只能運行於32位地址空間的機器上。但是可以創建一個Java虛擬機,它自動地把位元組碼轉換成64位的形式。從Java虛擬機支持的數據類型可以看出,Java對數據類型的內部格式進行了嚴格規定,這樣使得各種Java虛擬機的實現對數據的解釋是相同的,從而保證了Java的與平台無關性和可
移植性。
二、Java虛擬機體系結構
Java虛擬機由五個部分組成:一組指令集、一組寄存器、一個棧、一個無用單元收集堆(Garbage-collected-heap)、一個方法區域。這五部分是Java虛擬機的邏輯成份,不依賴任何實現技術或組織方式,但它們的功能必須在真實機器上以某種方式實現。
Java指令集
Java虛擬機支持大約248個位元組碼。每個位元組碼執行一種基本的CPU運算,例如,把一個整數加到寄存器,子程序轉移等。Java指令集相當於Java程序的匯編語言。
Java指令集中的指令包含一個單位元組的操作符,用於指定要執行的操作,還有0個或多個操作數,提供操作所需的參數或數據。許多指令沒有操作數,僅由一個單位元組的操作符構成。
虛擬機的內層循環的執行過程如下:
do{
取一個操作符位元組;
根據操作符的值執行一個動作;
}while(程序未結束)
由於指令系統的簡單性,使得虛擬機執行的過程十分簡單,從而有利於提高執行的效率。指令中操作數的數量和大小是由操作符決定的。如果操作數比一個位元組大,那麼它存儲的順序是高位位元組優先。例如,一個16位的參數存放時佔用兩個位元組,其值為:
第一個位元組*256+第二個位元組位元組碼指令流一般只是位元組對齊的。指令tabltch和lookup是例外,在這兩條指令內部要求強制的4位元組邊界對齊。
2.寄存器
Java虛擬機的寄存器用於保存機器的運行狀態,與微處理器中的某些專用寄存器類似。
Java虛擬機的寄存器有四種:
pc:Java程序計數器。
optop:指向操作數棧頂端的指針。
frame:指向當前執行方法的執行環境的指針。
vars:指向當前執行方法的局部變數區第一個變數的指針。
Java虛擬機
Java虛擬機是棧式的,它不定義或使用寄存器來傳遞或接受參數,其目的是為了保證指令集的簡潔性和實現時的高效性(特別是對於寄存器數目不多的處理器)。
所有寄存器都是32位的。
3.棧
Java虛擬機的棧有三個區域:局部變數區、運行環境區、操作數區。
(1)局部變數區 每個Java方法使用一個固定大小的局部變數集。它們按照與vars寄存器的字偏移量來定址。局部變數都是32位的。長整數和雙精度浮點數占據了兩個局部變數的空間,卻按照第一個局部變數的索引來定址。(例如,一個具有索引n的局部變數,如果是一個雙精度浮點數,那麼它實際占據了索引n和n+1所代表的存儲空間。)虛擬機規范並不要求在局部變數中的64位的值是64位對齊的。虛擬機提供了把局部變數中的值裝載到操作數棧的指令,也提供了把操作數棧中的值寫入局部變數的指令。
(2)運行環境區 在運行環境中包含的信息用於動態鏈接,正常的方法返回以及異常傳播。
·動態鏈接
運行環境包括對指向當前類和當前方法的解釋器符號表的指針,用於支持方法代碼的動態鏈接。方法的class文件代碼在引用要調用的方法和要訪問的變數時使用符號。動態鏈接把符號形式的方法調用翻譯成實際方法調用,裝載必要的類以解釋還沒有定義的符號,並把變數訪問翻譯成與這些變數運行時的存儲結構相應的偏移地址。動態鏈接方法和變數使得方法中使用的其它類的變化不會影響到本程序的代碼。
·正常的方法返回
如果當前方法正常地結束了,在執行了一條具有正確類型的返回指令時,調用的方法會得到一個返回值。執行環境在正常返回的情況下用於恢復調用者的寄存器,並把調用者的程序計數器增加一個恰當的數值,以跳過已執行過的方法調用指令,然後在調用者的執行環境中繼續執行下去。
·異常和錯誤傳播
異常情況在Java中被稱作Error(錯誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:①動態鏈接錯,如無法找到所需的class文件。②運行時錯,如對一個空指針的引用
·程序使用了throw語句。
當異常發生時,Java虛擬機採取如下措施:
·檢查與當前方法相聯系的catch子句表。每個catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。
·與異常相匹配的catch子句應該符合下面的條件:造成異常的指令在其指令范圍之內,發生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那麼系統轉移到指定的異常處理塊處執行;如果沒有找到異常處理塊,重復尋找匹配的catch子句的過程,直到當前方法的所有嵌套的catch子句都被檢查過。
·由於虛擬機從第一個匹配的catch子句處繼續執行,所以catch子句表中的順序是很重要的。因為Java代碼是結構化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計數器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計數器值下發生的異常情況。
·如果找不到匹配的catch子句,那麼當前方法得到一個"未截獲異常"的結果並返回到當前方法的調用者,好像異常剛剛在其調用者中發生一樣。如果在調用者中仍然沒有找到相應的異常處理塊,那麼這種錯誤傳播將被繼續下去。如果錯誤被傳播到最頂層,那麼系統將調用一個預設的異常處理塊。
(3)操作數棧區 機器指令只從操作數棧中取操作數,對它們進行操作,並把結果返回到棧中。選擇棧結構的原因是:在只有少量寄存器或非通用寄存器的機器(如Intel486)上,也能夠高效地模擬虛擬機的行為。操作數棧是32位的。它用於給方法傳遞參數,並從方法接收結果,也用於支持操作的參數,並保存操作的結果。例如,iadd指令將兩個整數相加。相加的兩個整數應該是操作數棧頂的兩個字。這兩個字是由先前的指令壓進堆棧的。這兩個整數將從堆棧彈出、相加,並把結果壓回到操作數棧中。
每個原始數據類型都有專門的指令對它們進行必須的操作。每個操作數在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數只能被適用於其類型的操作符所操作。例如,壓入兩個int類型的數,如果把它們當作是一個long類型的數則是非法的。在Sun的虛擬機實現中,這個限制由位元組碼驗證器強制實行。但是,有少數操作(操作符pe和swap),用於對運行時數據區進行操作時是不考慮類型的。
4.無用單元收集堆
Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規定具體使用的無用單元收集演算法,可以根據系統的需求使用各種各樣的演算法。
5.方法區
方法區與傳統語言中的編譯後代碼或是Unix進程中的正文段類似。它保存方法代碼(編譯後的java代碼)和符號表。在當前的Java實現中,方法代碼不包括在無用單元收集堆中,但計劃在將來的版本中實現。每個類文件包含了一個Java類或一個Java界面的編譯後的代碼。可以說類文件是Java語言的執行代碼文件。為了保證類文件的平台無關性,Java虛擬機規范中對類文件的格式也作了詳細的說明。其具體細節請參考Sun公司的Java虛擬機規范。
Ⅶ 編譯器和虛擬機有什麼聯系和區別
編譯器負責把你寫的JAVA代碼編譯成機器可以使用的機器代碼.開始編譯成位元組碼(.CLASS後綴),後續還會編譯成匯編語言. .編譯好的機器運行的代碼.最後跑在虛擬機上.
Ⅷ java編譯器把java程序編譯成虛擬機可以識別的二進制代碼,稱為什麼
由java編譯器把源文件編譯成虛擬機可以識別的二進制代碼稱為位元組碼。
而位元組碼是由java解釋器去解釋執行的。
Ⅸ java虛擬機和java編譯器是什麼關系和區別 他倆分別是干什麼的
編譯器就是把java源代碼編譯成位元組碼。java不生成exe的,保證了跨平台性。這個位元組碼就可以運行在java的虛擬機上java virtual machine