介紹

這一篇是 Java 基本語法介紹的第一篇,我們將由淺入深來探討程式碼架構。

Java 基礎觀念

  • Java 是以類別(class)型態為單位,且大小寫有所區別。
  • 一個檔案可以包含一個以上的類別,但最多只能有一個公開的接口,而這個接口由唯一的公用(public)的類別來表示。

    如果一個檔案內有多個 public 類別,編譯器會無法判定執行入口。

  • 一個應用程式,必須有一個「程式進入點」,程式的進入點必須宣告為靜態的 main 方法。
  • { }內的程式屬於同一個區塊。
  • 每行程式的尾段都必須要加上;來代表結束;大括號除外。

Hello Java

剛開始學程式一定會遇到的開頭式,就是教你怎麼打印輸出Hello world

1
2
3
4
5
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}
  • public class Main: Java 程式碼必須要在 class 裡面,class 的名稱必須要和檔案名稱一樣。
  • public static void main(String[] args): 程式的入口地址,Java 運行時先找 main 方法;和 C 語言的 main()函數用法一樣。
  • System.out.println("Hello World!");: 印出字串。

註解

在 Java 中有兩種註解方式。

1
2
3
4
5
6
7
// 單行註解

/*
多行註解1
多行註解2
......
*/

類別的宣告與建構

我們要如何宣告類別並建構出來。
以下範例可以看到 Main 為程式的進入點;Printer 為我們宣告的類別。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Printer {
public int PN; // 定義類別的屬性

public void hello() {
System.out.println("你好,Java");
System.out.println("序號:" + PN);
}
}

public class Main {
public static void main(String[] args) {
Printer pt = new Printer();
pt.PN = 1234567;
pt.hello();
}
}
  • Printer pt: 把 Printer 這個類別命名為 pt
  • new Printer(): 建構一個 Printer 類別。
  • pt.PN: ptPN 屬性。
  • pt.hello(): 呼叫 pthello 方法。
  • public void hello(): 回傳值類型為 void 則代表沒有回傳值。

沒有加上 public 的類別屬於預設存取權限(default),表示該類別只可以被同一個 package 裡的其他類別所存取。

類別宣告

1
2
3
4
<修飾語> class <類別名稱> {
屬性;
方法;
}

屬性宣告

1
<修飾語> <類型> <屬性名稱> [=初始值];

[ ]: 表示可選內容(option)。

方法宣告

1
2
3
<修飾語> <回傳值類型> <方法名稱>(<接收的參數>) {
程式敘述;
}

修飾語

Public

任何地方都能存取,即使跨 package 也能夠存取。

1
2
3
4
5
6
public class Cat {
public String name;
public void meow() {
System.out.println("Meow!");
}
}

不論在哪個檔案或 package,都可以 new Cat 存取 name 和 meow() 方法。

Protected

在同一 package 內可使用,或是不同 package 的子類別也可以存取。

1
2
3
4
5
6
7
8
class Animal {
protected String sound = "generic";
}
class Dog extends Animal {
public void bark() {
System.out.println(sound); // 可以存取父類 protected 屬性
}
}

Dog 類別(即使不同 package)可以存取父類 Animal 的 protected 屬性,不是子類或同個 package 就不能存取。

Default

類別與方法僅限同個 package 存取。

1
2
3
4
5
6
class Student {
int id;
void printId() {
System.out.println(id);
}
}

預設型態,無修飾詞。

Private

範圍是最小的,只能在定義它的範圍區域內使用。

1
2
3
4
5
6
7
8
9
class BankAccount {
private double balance;
public void deposit(double amount) {
balance += amount;
}
public double getBalance() {
return balance;
}
}

非存取權限修飾詞

有很多非存取權限修飾詞,以下僅列出常用的「非存取權限修飾詞」:

Static

static 被載入時就會分配記憶體,在整個程式執行期間都會存在,不會因為創建新物件而被重複分配。所有該類別的物件都共用同一份 static 成員,無論建立多少物件,static 變數只有一份。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Counter {
public static int count = 0;

public static void add() {
count++;
}
}

public class Main {
public static void main(String[] args) {
Counter.add();
Counter.add();
System.out.println("Count: " + Counter.count);
}
}

Final

用來設定 Only read 屬性,不可被覆寫、不能被繼承。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
final class MathUtil {
public static final double PI = 3.14159;

public final void show() {
System.out.println("不可覆寫的方法");
}
}

public class Main {
public static void main(String[] args) {
System.out.println("PI: " + MathUtil.PI);
MathUtil mu = new MathUtil();
mu.show();
}
}

Abstract

抽象類別或物件,用來當作一個模板,需要使用時可以繼承並實作有抽象屬性的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
abstract class Animal {
int height = 100;
int weight = 100;

abstract void name();
}

class Dog extends Animal {
void name() {
System.out.println("狗");
}

void printInfo() {
System.out.printf("height: %d\nweight: %d\n", height, weight);
}
}

public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name();
dog.printInfo();
}
}

在繼承時需要實作所有抽象的方法。

建構物件

上面介紹了如何宣告類別並建構,當我們創建一個類別就是創建了一個物件。意思是依據類別的宣告,配置記憶體空間,再將空間位址指定給物件名稱。

我們除了可以創建類別,也可以導入 Java 內建的類別使用。
下列範例使用了內建的 Scanner 類別,讓我們能夠取得輸入資訊。

1
2
3
4
5
6
7
8
9
10
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("請輸入學生分數:");
int scoreOfStudent = scanner.nextInt();
System.out.println("該生是否及格? " + (scoreOfStudent >= 60 ? "是" : "否"));
}
}
  • Scanner(System.in): 讀取輸入設備。
  • scanner.nextInt(): 讀取鍵盤上輸入的整數。

導入宣告

有兩種方式可以導入套件類別,一種是指定類別名稱;另一種是讀取所有類別。

1
2
import <套件名稱>.<類別名稱>;
import <套件名稱>.*;

資料類型

原生資料類型

名稱 說明 資料類型 可儲存範圍 佔用空間
整數 只能儲存整數 byte -128~127 1 byte
short -32768~32767 2 bytes
int -2147483648~2147483647 4 bytes
long -9223372036854775808~9223372036854775807 8 bytes
浮點數 儲存小數 float -3.4*1038~3.4*1038 (小數後6到7位) 4 bytes
雙精度浮點數 儲存小數(範圍更大) double -1.7*10308~1.7*10308 (小數後15位) 8 bytes
字元 字元採用 Unicode 的編碼 char '\u0000' ~ '\uffff' 2 bytes
布林值 就是布林值 boolean True / False 2 bytes

字元與字串的表示: ' ' 代表單一字元;" " 代表由多個字元組成的字串。

參考資料類型

Java 支援參考資料類型(Reference Data Type),是物件在記憶體中堆區的參考位址,而非物件本身的值。因此,當參考變數被賦值時,是複製物件的記憶體地址,而非物件本身。我們可以使用 new 來建立物件。
以下是參考資料類型的種類:

  • 類別(class): 用於創建物件的模板,裡面定義物件的屬性與方法。
  • 介面(interface): 定義一組方法,讓類別可以使用這些方法。
  • 陣列(array): 儲存同類型的元素集合。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Main {
public static void main(String[] args) {
// 創建 Point 物件 p1
Point p1 = new Point(1, 2);
System.out.println("p1 的座標為: (" + p1.x + ", " + p1.y + ")");
}
}

// 定義 Point 類別
class Point {
int x, y;

public Point(int a, int b) {
x = a;
y = b;
}
}

預設值

使用資料類型宣告一個變數時,如果沒有指定值,則會自動設定一個初始值。

類型名稱 預設值
整數 0
浮點數 0.0
字元 “”
布林值 False

範例程式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Main {
static byte defaultByte;
static short defaultShort;
static int defaultNumber;
static long defaultLong;
static float defaultFloat;
static double defaultDouble;
static char defaultChar;
static boolean defaultBoolean;

public static void main(String[] args) {
System.out.println("Default byte: " + defaultByte);
System.out.println("Default short: " + defaultShort);
System.out.println("Default int: " + defaultNumber);
System.out.println("Default long: " + defaultLong);
System.out.println("Default float: " + defaultFloat);
System.out.println("Default double: " + defaultDouble);
System.out.println("Default char: " + defaultChar);
System.out.println("Default boolean: " + defaultBoolean);
}
}

查看資料類型

必須將指定變數轉為物件型態才能查看該變數的類型。

1
2
x = 123;
System.out.println(((Object)x).getClass().getSimpleName()); // Integer

等同於

1
2
Object x = 123;
System.out.println(x.getClass().getSimpleName());

資料類型轉換

有三種轉換變數類型的方式:

  • (int)<變數名稱>: 將指定變數轉換成 int 類型。
  • (char)<變數名稱>: 將指定變數轉換成 char 類型。
  • (double)<變數名稱>: 將指定變數轉換成 double 類型。
1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args) {
int score = 85;
double newScore = (double) score;
System.out.println("原始成績: " + score);
newScore = Math.sqrt(newScore) * 10;
System.out.println("開根號乘 10 後的成績: " + newScore);
}
}

變數宣告與命名

變數宣告

Java 是一種嚴格型態 (Strong-typed) 的程式語言,變數在使用之前一定要先宣告該變數的資料型別。

宣告的主要目的是依據資料類型來配置記憶體空間。

1
2
3
4
5
6
7
8
public class Main {
public static void main (String[] args){
int i, j=10; //宣告 i, j 兩個整數變數,將 10 只指定給變數 j
i=20; //將 20 指定給變數 i
System.out.println( "變數i的內容 = " + i );
System.out.println( "變數j的內容 = " + j );
}
}

有三種宣告方式:

一般宣告

1
<資料類型> <變數名稱> [=初始值];

[ ]: 表示可選內容(option)。

重複的資料型別變數

1
<資料類型> <變數名稱1>,<變數名稱2>,...;

重複的資料型別變數 (指定初始值)

1
<資料類型> <變數名稱1> = <初始值>,<變數名稱2> = <初始值>,...;

命名方式

在命名時盡量使用良好的命名規則,不僅方便辨識其變數代表的意思,也方便知道其所屬的資料型別。
常見的命名方式: 駝峰式 (大駝峰 / 小駝峰)、蛇型命名 (Snake Case)、烤肉串命名 (Kebab Case)、匈牙利命名法 (Hungarian notation)

以下是 Java 推薦的命名方式。(僅供參考)

類型 命名規則 範例
Class 每個單字的字首大寫 (大駝峰) Printer, NumberCounter
Method 第一個單字字首小寫,其餘字首大寫 (小駝峰),通常是動作 + 用途 splitData, getCodeBase
Variable 第一個單字字首小寫,其餘字首大寫 (小駝峰),通常是型別 + 用途 iCount, bFlag
Constant 每個字大寫,並使用底線區隔單字 MAX_NUMBER, MIN_NUMBER

字串 String

逃脫字元

逃脫字元 (Escape Character),又稱溢出字元。有兩種使用目的:

  • 會被判斷是命令的字母或符號。
  • 需要在字串中輸出特殊字元。

以下是常見的逃脫字元:

字元 說明
\b Backspace 鍵
\n 換行符號
\t Tab 鍵
\" 輸出雙引號
\’ 輸出單引號
\\ 輸出反斜線

逃脫字元都是由 \ + 特定字元 組成。

字串的方法

因為字串屬於一個物件,所以也具備了屬性與方法。

方法 功能
length() 取得字串字元數量。
equals() 比較兩個字串的內容是否相同。(回傳 true / false)
toLowerCase() 將字串內容轉換為小寫。
toUpperCase() 將字串內容轉換為大寫。
substring(起始位址) 擷取起始位址以後的字。
substring(起始位址, 結束的下個位址) 擷取起始位址到結束位址之間的字。
indexOf(字串) 尋找特定字串,回傳第一次出現的位址。(找不到則為 -1)
lastIndexOf(字串) 尋找特定字串,回傳最後一次出現的位址。(找不到則為 -1)
replace(舊字串, 新字串) 取代舊字串。

資料輸出

我們可以使用 Java 內建的 System.out 類別的方法將內容顯示在螢幕上。
System.out 提供了三種方式: print(), println(), printf()

無換行式輸出

文字輸出時會接續內容,不會換行。

1
2
System.out.print("你好!")
System.out.print("我是XXX")

換行式輸出

每次輸出時都會換行。

1
2
System.out.println("這是一段文字1")
System.out.println("這是一段文字2")

格式化輸出

可以在指定位置插入特定值。
以下為格式化輸出的方式:

  • %nd: 十進位整數。
  • %m.nf: 十進位浮點數格式。
  • %no: 八進位數。
  • %nu: 無符號的十進位數字。
  • %nx: 十六進位數。
  • %nc: 單一個字元。
  • %ns: 字串。
  • %%: 輸出 % 符號。
1
2
3
4
int x = 100;
double y = 252.55;
System.out.printf("Hello, %s. You are %d years old.\n", "Ray", 21);
System.out.printf("座標位置: x = %d, y = %.2f\n", x, y);

靠左對齊 & 靠右對齊

格式化輸出方式:

  • %<字元數>: 靠右對齊 (預設)。
  • %-<字元數>: 靠左對齊。
1
2
System.out.printf("[%10d]", 100); //  [       100]
System.out.printf("[%-10d]", 100); // [100 ]

下一篇將會繼續介紹 Java 的基礎語法。