在Java的世界中,並非每個東西抽象化為物件,你還是要面對系統的一些特性,例如,你還是要意會到記憶體長度有限的問題,所以程式執行時遇到123這個整數時,你還是要想一下,用多少長度的記憶體來儲存它會比較經濟。基本上,Java可區分為兩大型態系統:
- 基本型態(Primitive type)
- 類別型態(Class type),亦稱參考型態(Reference type)
這邊先解釋基本型態,之後會說明類別型態。
所謂基本型態,就是你在使用時,得考慮一下資料用多少記憶體長度來存比較經濟,利用程式語法告訴JVM,然後由JVM自動為你在記憶體中配置與管理。在Java中的基本型態主要可區分為整數、位元組、浮點數、字元與布林:
- 整數
可細分為short
整數(佔2個位元組)、int
整數(佔4個位元組)與long
整數(佔8個位元組)。不同長度的整數,可儲存的整數範圍也不同。long
整數佔的記憶體長度比int
整數來得多,可表示的整數範圍也就比int
整數大。同樣的,int
整數可表示的整數範圍也比短整數來得大。
- 位元組
byte
型態顧名思義,長度就是一個位元組,在需要逐位元組處理資料時(例如影像處理、編碼處理等),就會使用byte
型態,若用於表示整數,byte
可表示-128到127的整數。
- 浮點數
主要用來儲存小數數值,可分為float
浮點數(佔4個位元組)與double
浮點數(佔8個位元組),double
浮點數使用的記憶體空間比float
浮點數來得多,可表示的精確度也比較大。
- 字元
char
型態用來儲存'A'
、'B'
、'林'
等字元符號。在JDK8中,Java的字元採Unicode 6.2編碼,JVM實作採UTF-16 Big Endian,所以每個字元型態佔兩個位元組,中文字元與英文字元在Java中同樣都是用兩個位元組儲存。
有關編碼、Unicode、UTF 等,可以參考 哪來的純文字檔?,以及 Unicode 與 UTF。
- 布林
boolean
型態可表示true
與false
,分別代表邏輯的「真」與「假」。在Java中不用在意boolean
型態的長度,因為你也無法將boolean
型態與其它型態作運算。
每種型態佔有的記憶體長度不同,可儲存的數值範圍也就不同。例如int型態的記憶體空間是4個位元組,所以可儲存的整數範圍為-2147483648至2147483647,如果儲存值超出型態範圍稱之為溢值(Overflow),會造成程式不可預期的結果。不用記憶各種型態可儲存的數值範圍,可以透過API來得知。例如:
package cc.openhome;
public class Range {
public static void main(String[] args) {
// byte、short、int、long 範圍
System.out.printf("%d ~ %d%n",
Byte.MIN_VALUE, Byte.MAX_VALUE);
System.out.printf("%d ~ %d%n",
Short.MIN_VALUE, Short.MAX_VALUE);
System.out.printf("%d ~ %d%n",
Integer.MIN_VALUE, Integer.MAX_VALUE);
System.out.printf("%d ~ %d%n",
Long.MIN_VALUE, Long.MAX_VALUE);
// float、double 精度範圍
System.out.printf("%d ~ %d%n",
Float.MIN_EXPONENT, Float.MAX_EXPONENT);
System.out.printf("%d ~ %d%n",
Double.MIN_EXPONENT, Double.MAX_EXPONENT);
// char 可表示的 Unicode 範圍
System.out.printf("%h ~ %h%n",
Character.MIN_VALUE, Character.MAX_VALUE);
// boolean 的兩個值
System.out.printf("%b ~ %b%n",
Boolean.TRUE, Boolean.FALSE);
}
}
對於初學Java,會看到一些新的語法與API在裏頭,以下逐一解釋。
你在程式中看到//
符號,這是Java程式中的單行註解,註解是用來說明或記錄程式中一些注意事項,編譯器會忽略該行//
符號之後的文字,對編譯出來的程式不會有任何影響,另一個註解符號是/*
與*/
包括的多行註解。例如:
/* 作者:良葛格
功能:示範printf()方法
日期:2011/7/23
*/
public class Demo {
...
編譯器會忽略/*
與*/
間的文字,不過以下使用多行註解的方式是不對的:
/* 註解文字1……bla…bla
/*
註解文字2……bla…bla
*/
*/
編譯器會以為倒數第二個*/就是註解結束的時候,因而對最後一個*/就會認為是錯誤的語法,這時就會出現編譯錯誤的訊息。
在第一個Java程式顯示Hello World時,使用了System.out.println()
,這會在標準輸出中顯示文字後換行,如果使用System.out.print()
,則輸出文字後不會換行。那麼System.out.printf()
是什麼?printf()
是JDK5之後才有API,f就是format的意思,也就是格式化,用在System.out
上,就是對輸出文字作格式化後再顯示在文字模式中。printf()
的第一個引數(Argument)是字串,當中%d
、%h
、%b
等是格式控制符號。以下列出一些常見的格式控制字元:
符號 |
說明 |
%% |
因為% 符號已經被用來作為控制符號前置,所以規定使用%% 才能在字串中表示% 。 |
%d |
以10進位整數格式輸出,可用於byte、short、int、long、Byte、Short、 Integer、Long或BigInteger 。 |
%f |
以10進位浮點數格式輸出,可用於float、double、Float、Double或BigDecimal 。 |
%e, %E |
以科學記號浮點數格式輸出,提供的數必須是float、double、Float、 Double或BigDecimal 。%e 表示輸出格式遇到字母以小寫表示,如2.13 e+12,%E 表示遇到字母以大寫表示。 |
%o |
以8進位整數格式輸出,可用於byte、short、int、long、Byte、Short、 Integer、Long或BigInteger 。 |
%x, %X |
以16進位整數格式輸出,可用於byte、short、int、long、Byte、Short、 Integer、Long或BigInteger 。%x 表示字母輸出以小寫表示,%X 則以大寫表示。 |
%s, %S |
字串格式符號。 |
%c, %C |
以字元符號輸出,提供的數必須是byte、short、char、Byte、Short、Character或Integer 。%c 表示字母輸出以小寫表示,%C 則以大寫表示。 |
%b, %B |
輸出boolean 值,%b 表示輸出結果會是true或false,%B 表示輸出結果會是TRUE或FALSE。非null 值輸出是true或TRUE,null 值輸出是false或FALSE。 |
%h, %H |
使用Integer.toHexString(arg.hashCode()) 來得到輸出結果,如果arg 是null ,則輸出null,也常用於想得到16進位格式輸出。 |
%n |
輸出平台特定的換行符號,如果Windows下會置換為"\r\n" ,如果是Linux下則會置換為'\n' ,Mac OS下會置換為'\r' 。 |
printf()
方法的第二個引數開始,會依序置換掉第一個引數的格式控制符號。Byte、Short、Integer、Long、Float、Double、Character、Boolean
,這些都是java.lang
套件下的類別,下一章就會談到,這些類別都是基本型態的包裹器(Wrapper),至於MAX_VALUE、MIN_VALUE、MIN_EXPONENT、MAX_EXPONENT、TRUE、FALSE
等,都是這些類別上的靜態(static
)成員(其實System
中的out
也是),別擔心,之後還會解釋何謂靜態成員,就目前來說,直接使用就對了。
這個範例的輸出結果如下:
-32768 ~ 32767
-2147483648 ~ 2147483647
-9223372036854775808 ~ 9223372036854775807
-126 ~ 127
-1022 ~ 1023
0 ~ ffff
true ~ false
可以在輸出浮點數時指定精度,例如以下這行的執行結果會輸出" example:19.23":
System.out.printf("example:%.2f%n", 19.234);
也可以指定輸出時,至少要預留的字元寬度,例如:
System.out.printf("example:%6.2f%n", 19.234);
由於預留了6個字元寬度,不足的部份要由空白字元補上,所以執行結果會輸出" example: 19.23"(19.23只佔五個字元,所以補了一個空白在前端)。