- 註冊時間
- 2006-10-8
- 最後登錄
- 2019-6-20
- 主題
- 查看
- 積分
- 1306
- 閱讀權限
- 110
- 文章
- 1393
- 相冊
- 0
- 日誌
- 1
   
狀態︰
離線
|
Java Virtual Machine
C語言的開發模式, 是編寫.c的Source Code, 再經由Compiler編譯成Object Code。所謂Object Code指的是和硬體相關的機器指令, 也就是說當我們想要把C程式移植到不同的硬體時, 必須要重新Compile,以產生新的執行檔。除了需要重新編譯外,新系統是否具備應用程式所需的程式庫,include的檔案是否相容, 也是程式能否在新機器上順利編譯和執行的條件之一。
在實務上,為了讓C程式能在不同的UNIX版本上都能順利編譯,原作者往往必須使用前置處理器的#ifdef指令,判斷不同環境的適當寫法。如果想把在UNIX上開發的C程式移植到Windows上,則有用到專屬程式庫的部分(如UNIX的使用者介面可能用到X Window的API,Windows就沒有支援,必須一台一台灌程式庫才行,很可能還要花錢買),就必須重寫才行。
解決此類問題的方法之一,是定義一種Virtual Machine(虛擬機器),讓程式語言編譯時不要翻成實體機器的指令,而是翻成Virtual Machine的目的碼。Virtual Machine一般是以軟體來模擬的,只要新的平台有Virtual Machine,則原始程式不用Compile,執行舊機器上已有的Virtual Machine目的碼,就可以了。當然要達到完全不用重新Compile就能執行的理想,還要配合標準的程式庫才行。
Java語言基於上述理念,定義了Java Virtual Machine,它所用的指令稱為byte code。使用Virtual Machine的缺點之一,是執行的速度較慢,代價是開發的速度變快了。以現在的硬體來說,大部分應用程式的執行速度已經沒有那麼重要,反倒是軟體的開發速度和品質越來越值得重視。
此外JVM的技術不斷進步, 諸如Just In Time(JIT) Compiler, 或HotSpot等技術都可以讓Java程式以非常接近原生碼(Native Code)的速度執行。因此不要因為某些偏頗的報告或直覺, 就不使用Java了。
開發Java應用程式的工具中,最常見的是由Java的原創公司Sun Micro所出版的JDK(Java Development Kit)。JDK可以免費下載。以Text Editor寫好的Hello.java原始檔:
public class Hello {
public static int gvar;
public static void say(String s) {
int x = 10;
System.out.print(s+x);
}
public static void main(String[] argv) {
float y = 0;
say("Hello, world\n");
}
}
這程式的C版本如下
#include <stdio.h>
int gvar;
void say(char[] s) {
int x = 10;
printf("%s%d", s, x);
}
int main(int argc, char** argv) {
float y = 0;
say("Hello, world\n");
}
經過:
javac Hello.java
編譯完成後會產生byte code格式的Hello.class,然後
java Hello
就可以利用Java Virtual Machine(此處是java這個執行檔)來執行了。
上述過程中幾個比較會發生的問題是
javac找不到: 請設定path這個環境變數。
javac抱怨class Hello找不到: 請確定你的檔名是大寫Hello.java,程式內的public class Hello有沒有大小寫的問題。
java抱怨找不到main: 請確定public static void main(String[] argv)毫無錯誤。
Java是物件導向(Object-Oriented)程式語言
Java是由C++簡化來的。由於C++要和C完全相容,又很注重效能問題,因此C++算是很複雜的程式語言。Java在設計之初,考量的重點之一就是簡單,因此和C++比起來,不僅更為物件導向,而且比C++容易學習。
Java許多運算符號和敘述語法都是來自C語言,假設各位已經對C語言有所了解,本章後面的部分只將Java和C在運算符號和敘述語法上的差異點出來,相同的部分請參見C語言的課程內容。
資料型別
Java語言所定義的基本資料型別有
型別名稱 位元長度 範圍
boolean 1 true或false
byte 8 -128 ~ 127
short 16 -32768 ~ 32767
char 16 Unicode characters
int 32 -2147483648 ~ 2147483647
long 64 -9223372036854775808 ~ 9223372036854775807
float 32 +-3.4028237*10+38 ~ +-1.30239846*10-45
double 64 +-1.76769313486231570*10+308 ~ 4.94065645841246544*10-324
Java的資料型態裡沒有unsigned。
Java對數值型態的轉換比C稍微嚴格一點,下列左邊的部分都可以指定(assignment)給右邊的型別:
byte --> short --> int --> long --> float --> double
除上述外,其他型別間的轉換都必須下達型別轉換(Type Casting)命令來處理,其形式為圓括弧裡寫上型別名稱,如(double)
由於Java在char的型態部分採用Unicode,因此字元常數的表示法,除因循C的規則外,也可以直接指定16bits Unicode編碼給char型別的變數。例如由Windows "字元對應表" 程式中可查到象棋中的紅車的unicode編碼為4FE5, Java可用 '\u4fe5' 來表達。Java的變數也可以用Unicode來命名,換句話說,你可以用中文取變數名稱。
除了這些基本資料型別外,Java還有一個稱為Reference(參考)的型別。Reference用來存取Object(物件),其功能和C語言的pointer用來存取記憶體有點像,但沒有pointer的&+-等運算符號,而且Reference只能存取型態相符合的類別。宣告Reference的語法是ClassName varName,例如
String s;
宣告s是一個型態為reference的變數,這表示我們可透過s來存取屬於String類別的物件(s is a reference to String object)。
要特別強調的是, s並不是物件, 而是用來指向String物件的reference。打個比方,
public class 動物 {
動物 手指頭; // java 因字元編碼使用unicode, 所以可用中文當變數名稱
public static void main(String[] arg) {
動物 手指頭2;
手指頭2 = new 動物();
}
}
變數 "手指頭" 宣告為reference, 可指向屬於 class "動物" 的物件, 手指頭不是動物, 而是用手指頭指向某隻動物。
java.lang.Float f;
java.lang.Double d;
java.lang.Integer i;
以上變數的型態都是reference
運算符號(Operator)
Java語言在運算式的部分,和C語言極為類似, 除了沒有sizeof, pointer和struct相關的運算符號外, 另外新增了>>>向右無號shift, 以及用來判斷物件型態的instanceof。Java的常數的表示法也和C相同,而Java裡的新資料型態boolean的合法值為true和false兩個常數。
算術(Arithmetic)運算符號
運算符號 功能敘述
+ 加
* 乘
- 減
/ 除
% 餘數
++ 加一
-- 減一
邏輯(logic)運算符號
運算符號 功能敘述
> 大於
< 小於
>= 大於等於
<= 小於等於
== 等於
!= 不等於
&& logic AND
|| logic OR
! logic NOT
instanceof reference instanceof ClassName
判斷reference所指到的物件其型態是否和ClassName相容
Java語言和C語言有關邏輯運算最大的不同,在於Java以boolean資料型態(只有true和false兩種值)判斷條件是否成立,而C語言只能使用0或非0。
位元(Bit)運算符號
運算符號 功能敘述
& bit AND
<< left bit shift
| bit OR
>> right bit shift with sign
^ bit XOR
~ 1補數
>>> 同>>但左邊一律補零
其他運算符號
運算元 功能敘述
= 將右邊的值複製到左邊的變數
(type) 將右邊的數值或reference轉換成type型別
+= 將右邊的數值加上左邊的數值然後指定給左邊的變數
?: 若?左邊成立則做:左邊否則做:右邊
, 合併兩個運算視為一個敘述
(運算式) 表示()內優先運算
. Reference.ObjectMember或ClassName.ClassName
存取物件或類別成員
new 產生物件
優先權
種類 運算符號 結合順序
group (op) left to right
postfix [] . (params) op++ op-- right to left
prefix ++op --op +op -op ~ ! right to left
creation or casting new (type)op right to left
multiplicative * / % left to right
additive + - left to right
shift << >> >>> left to right
relational < > <= >= instanceof == left to right
equality == != left to right
bitwise and & left to right
bitwise exclusive or ^ left to right
bitwise inclusive or | left to right
logical and && left to right
logical or || left to right
conditional ? : right to left
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>= right to left
seperator , left to right
流程控制敘述
Java的流程控制敘述和C語言極為類似,不同處在於break和continue兩個指令。Java的break和continue指令後面可以加上標籤,以指示要跳出或繼續的範圍。
public class BreakContinueExample {
public static void main(String[] argv) {
int i, j;
outerLoop:
for (i = 0; i < 100; i++) {
innerLoop:
for (j = 0; j < 100; j++) {
if (j == 50 && i == 50) {
break outerLoop;
}
}
}
System.out.println("Loop have been terminated.");
}
}
在上面的例子中,當j==50且i==50時,break指令會跳出最外面的迴圈,直接印出迴圈終止訊息。如果break後面沒有outerLoop的話, 只會跳出裡面的迴圈,然後i從51繼續做下去。
字串
C語言定義以0結尾的字元陣列就是字串。但對Java來說, 字串是由String類別來表達, 也就是說String是物件而不是陣列。由於我們經常使用字串, 為了寫作程式方便起見, Java Compiler碰到+符號某一邊的型態是String時, 就會把+翻譯成StringBuffer類別裡相對應的append Method。例如:
public class StringTest {
public static void main(String[] argv) {
int x = 5;
float y = 1.5;
System.out.println("x = " + x + ", y = " + y);
}
}
會翻譯成:
public class StringTest {
public static void main(String[] argv) {
int x = 5;
float y = 1.5;
System.out.println((new StringBuffer("x = ")).append(x).append(", y = ").append(y).toString());
}
}
如果你會C++, 看到Java字串+符號的語法, 千萬不要以為Java支援operator overloading。Java只是透過Compiler來做特別的轉換, 稱這種技術為Compiler Sugar比較適合。
Java語言的寫作風格
寫作Java程式時,請注意下列幾種風格
Class Name請首字大寫
Variable Name和Method Name請首字小寫
如果名稱由數個英文字組成,第二個英文字以後首字大寫
內縮四個空格
註解部分如要變成說明文件,請遵照javadoc這個工具的寫作規則
/**
* 第一行的兩個**用來告訴javadoc此部份註解要變成HTML文件的一部份
* 這段註解裡的所有文字都會變成此類別一開頭的說明
*/
public class Hello { // Class Name首字大寫
/**
* 此段註解會變成描述main方法的一部分
* @param argv 使用@param註記會產生參數(parameter)argv的相關說明
* @return 傳回值的意義說明
*/
public static void main(String[] argv) { // Method Name首字小寫
// argv: array of references to String object
int myVariable; // 變數宣告
int i, sum;
for (i = 1, sum = 0; i <= 100; i++) {
sum += i;
}
System.out.println("summation from 1 to 100 is "+sum);
}
|
-
總評分: 威望 + 2
查看全部評分
|