型態
May 19, 2022在 Java 的世界中,並非每個東西抽象化為物件,還是要面對系統的一些特性,例如,你還是要意會到記憶體長度有限的問題,程式執行時遇到 123 這個整數時,還是要想一下,用多少長度的記憶體來儲存它會比較經濟。
型態系統
基本上,Java 可區分為兩大型態系統:
- 基本型態(Primitive type)
- 類別型態(Class type),亦稱參考型態(Reference type)
這邊先解釋基本型態,之後會說明類別型態。
Java 的基本型態主要可區分為整數、位元組、浮點數、字元與布林:
- 整數
可細分為 short
整數(佔 2 個位元組)、int
整數(佔 4 個位元組)與 long
整數(佔 8 個位元組)。不同長度的整數,可儲存的整數範圍也不同。long
整數佔的記憶體長度比int整數來得多,可表示的整數範圍也就比 int
整數大。同樣地,int
整數可表示的整數範圍也比短整數來得大。
- 位元組
byte
型態長度就是一個位元組,在需要逐位元組處理資料時(例如影像處理、編碼處理等),就會使用 byte
型態,若用於表示整數,byte
可表示 -128 到 127 的整數。
- 浮點數
主要用來儲存小數數值,可分為 float
浮點數(佔 4 個位元組)與 double
浮點數(佔 8 個位元組),double
浮點數使用的記憶體空間比 float
浮點數來得多,可表示的精確度也比較大。
- 字元
Java 支援 Unicode,char
型態佔 2 個位元組,可用來儲存 UTF-16 Big Endian 的一個碼元(code unit),就現在而言,只要知道英文或中文字元可以直接寫在 ''
以 char
儲存,也可以把 65535 以內的整數指定給 char
。
- 布林
boolean
型態可表示 true
與 false
,分別代表邏輯的「真」與「假」,不用在意 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);
}
}
在程式中看到 //
符號,這是單行註解,註解是用來說明或記錄程式中一些注意事項,編譯器會忽略該行 //
符號之後的文字,對編譯出來的程式不會有任何影響,另一個註解符號是 /*
與 */
包括的多行註解。例如:
/* 作者:良葛格
功能:示範printf()方法
日期:2011/7/23
*/
public class Demo {
...
編譯器會忽略 /*
與 */
間的文字,不過以下使用多行註解的方式是不對的:
/* 註解文字1……bla…bla
/*
註解文字2……bla…bla
*/
*/
編譯器會以為倒數第二個 */
就是註解結束的時候,因而對最後一個 */
就會認為是錯誤的語法,這時就會出現編譯錯誤的訊息。
格式化輸出
System.out.println
會在標準輸出中顯示文字後換行,如果使用 System.out.print
,輸出文字後不會換行,System.out.printf
會對輸出文字作格式化後再顯示在文字模式中。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.13e+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'
。
這個範例的輸出結果如下:
-128 ~ 127
-32768 ~ 32767
-2147483648 ~ 2147483647
-9223372036854775808 ~ 9223372036854775807
-126 ~ 127
-1022 ~ 1023
0 ~ ffff
true ~ false
可以在輸出浮點數時指定精度,例如:
jshell> System.out.printf("example:%.2f%n", 19.234);
example:19.23
也可以指定輸出時,至少要預留的字元寬度,例如:
jshell> System.out.printf("example:%6.2f%n", 19.234);
example: 19.23
由於預留了 6 個字元寬度,不足的部份要由空白字元補上,所以執行結果會輸出 " example: 19.23"(19.23 只佔五個字元,所以補了一個空白在前端)。
字面常量
在 Java 寫下一個值,該值稱為字面常量(Literal constant)。在整數字面常量表示上,除了 10 進位表示法之外,還有8進位或16進位表示。例如 12 這個值分別以 10 進位、16 進位與 8 進位表示:
jshell> 12 // 10 進位表示
$1 ==> 12
jshell> 0xC // 16 進位表示,以 0x 開頭
$2 ==> 12
jshell> 014 // 8 進位表示,以 0 開頭
$3 ==> 12
浮點數除了使用小數方式直接表示外,也可以直接使用科學記號表示。例如以下都是表示 0.00123 的值:
jshell> 0.00123
$4 ==> 0.00123
jshell> 1.23e-3
$5 ==> 0.00123
要表示字元的話,必須使用 '
符號括住字元,這會是個 char
型態。例如:
jshell> 'S'
$6 ==> 'S'
jshell> '林'
$7 ==> '林'
像 '
這個符號在語法上用來表示字元,若就是想表示 '
這個字元呢?必須使用忽略(Escape)符號 \
,編譯器看到 \
會忽略下個字元,不視為程式語法的一部份。例如要表示 '
就要用 \'
。
以下是常用的一些忽略符號:
\\
:反斜線\
。\'
:單引號'
。\"
:雙引號"
。\uxxxx
:以 16 進位數指定char
的值,x
表示數字。\xxx
:以 8 進位數指定char
的值,x
表示數字。\b
:倒退一個字元。\f
:換頁。\n
:換行。\r
:游標移至行首。\t
:跳格(按下 Tab 鍵的字元)。
撰寫整數或浮點數字面常量時,可以使用底線更清楚地表示某些數字。例如:
jshell> 1234_5678
$9 ==> 12345678
jshell> 3.141_592_653
$10 ==> 3.141592653
有時候,想以二進位方式表示某個值,可以用 0b
作為開頭。例如:
jshell> 0b101010101010 // 用二進位表示 10 進位整數 2730
$11 ==> 2730
上面的程式片段也可以結合底線,這樣就更清楚了:
jshell> 0b1010_1010_1010 // 用二進位表示 10 進位整數 2730
$12 ==> 2730