第一單元:java平臺概述
JAVA語言:
跟任何編程語言一樣,Java 語言擁有自己的結構、語法規則和編程范例。Java 語言的編程范例基于面向對象編程 (OOP) 的概念,該語言的特性支持這一概念。
Java 語言是 C 語言的一種衍生語言,所以它的語法規則與 C 語言的語法規則非常相似。例如,方法使代碼模塊化并使用花括號({ 和 })分隔,變量需要在使用之前聲明。
在結構上,Java 語言以包 作為開頭。包是 Java 語言的命名空間機制。包中包含類,而類中包含方法、變量、常量等。
JVM:
在 Java 平臺編寫程序時,您會在 .java 文件中編寫源代碼,然后編譯它們。編譯器針對語言的語法規則來檢查代碼,然后將字節碼 寫出到 .class 文件中。字節碼是一組需要在 Java 虛擬機 (JVM) 上運行的指令。
在運行時,JVM 讀取并解釋 .class 文件,在編寫的 JVM 的目標原生硬件平臺上執行程序的指令。JVM 解釋字節碼就像 CPU 解釋匯編語言指令一樣。不同之處在于,JVM 是一個專為特定平臺編寫的軟件。JVM 是 Java 語言的 “編寫一次、隨處運行” 原則的核心。您的代碼可在任何擁有合適的 JVM 實現的芯片集上運行。
垃圾收集器
Java 平臺不會強制您時刻關注內存分配(或使用第三方庫來完成此工作),它提供了開箱即用的內存管理功能。當您的 Java 應用程序在運行時創建一個對象實例時,JVM 會自動從堆 中為該對象分配內存空間— 堆是一個專門留給您的程序使用的內存池。Java 垃圾收集器 在后臺運行,跟蹤記錄應用程序不再需要哪些對象并從它們回收內存。這種內存處理方法稱為隱式內存管理,因為它不需要您編寫任何內存處理代碼。垃圾收集是 Java 平臺性能的基本特征之一。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-java-platform-overview/index.html
第 2 單元:設置 Java 開發環境
第 3 單元:面向對象編程的概念和原理
什么是對象?
Java 語言(基本上)是面向對象的。
面向對象的語言遵循的編程模式不同于結構化編程語言,比如 C 和 COBOL。結構化編程范例是高度面向數據的:您擁有數據結構,然后程序指令處理該數據。面向對象的語言(比如 Java 語言)將數據和程序指令組合到對象 中。
對象是一個自成一體的實體,它僅包含屬性和行為,不含任何其他內容。不需要擁有包含字段(屬性)的數據結構并將該結構傳遞到處理它(行為)的所有程序邏輯,在面向對象的語言中,數據和程序邏輯組合在一起。
OOP的原則
封裝
回想一下,一個對象是離散的或獨立的。此特征是封裝 的工作原理。對象在它的狀態和行為與外部世界之間保持一條界線。在 Java 平臺上,可以使用訪問修飾符(后面將會介紹)來區分公共 與私有 對象關系的性質。公共訪問是完全開放的,而私有訪問意味著對象的屬性僅可在對象自身內訪問。
公共/私有邊界采取面向對象的封裝原則。在 Java 平臺上,可以逐個對象地改變該邊界的強度。封裝是 Java 語言的一個強大特性。
繼承
OOP 引入了繼承 的概念,使得特殊化的類 — 無需額外的代碼 — 可以 “復制” 它們要特殊化的來源類的屬性和行為。如果其中一些屬性或行為需要更改,您可覆蓋它們。您更改的唯一的源代碼是創建特殊化的類所需的代碼。來源對象稱為父對象,新的特殊化對象稱為子對象
多態性
在本質上,多態性表示屬于一個分層結構的同一個分支的對象,在發送相同的消息時(也即在被告知執行同一件事時),可通過不同方式表現出該行為。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-object-oriented-programming-concepts-and-principles/index.html
第 4 單元:Java 語言入門
java類的結構
package packageName;
import ClassNameToImport;
accessSpecifier class ClassName {
accessSpecifier dataType variableName [= initialValue];
accessSpecifier ClassName([argumentList]) {
constructorStatement(s)
}
accessSpecifier returnType methodName ([argumentList]) {
methodStatement(s)
}
// This is a comment
/* This is a comment too */
/* This is a
multiline
comment */
}
#實例
package com.makotojava.intro;
public class Person {
private String name;
private int age;
private int height;
private int weight;
private String eyeColor;
private String gender;
public Person() {
// Nothing to do...
}
public Person(String name, int age, int height, int weight String eyeColor, String gender) {
this.name = name;
this.age = age;
this.height = height;
this.weight = weight;
this.eyeColor = eyeColor;
this.gender = gender;
}
public String getName() { return name; }
public void setName(String value) { name = value; }
// Other getter/setter combinations...
}
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-getting-started-with-the-java-language/index.html
第 5 單元:您的第一個 Java 類
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-your-first-java-class/index.html
第 6 單元:向一個 Java 類添加行為
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-adding-behavior-to-a-java-class/index.html
第 7 單元:字符串和運算符
字符串
以下是兩種創建字符串的方法,我們以創建一個名為 greeting 且值為 hello 的 String 實例為例:
greeting = new String("hello");
String greeting = "hello";
#串聯字符串
str1 + str2
str1.concat(str2).concat(str3)
運算符
java 語言使用兩種類型的運算符:
- 一元:僅需要一個操作數。
- 二元:需要兩個操作數。
運算符 | 用法 | 描述 |
---|---|---|
++ | a++ | 將 a 遞增 1;計算遞增之前 a 的值 |
++ | ++a | 將 a 遞增 1;計算遞增之后 a 的值 |
-- | a-- | 將 a 遞減 1;計算遞減之前 a 的值 |
-- | --a | 將 a 遞減 1;計算遞減之后 a 的值 |
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-strings-and-operators/index.html
第 8 單元:條件運算符和控制語句
三元運算符
Java 語言提供了一個方便的運算符來執行簡單的 if / else 語句檢查。這個運算符的語法是:
(conditional) ? statementIfTrue : statementIfFalse;
如果 conditional 計算為 true,則執行 statementIfTrue;否則執行 statementIfFalse。每條語句均不允許采用復合語句形式。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-conditional-operators-and-control-statements/index.html
第 9 單元:循環
public boolean method3() {
boolean a = true;
boolean b = false;
boolean c;
if (a = b)
c = false;
else
c = a;
return c;
}
#答案是false
public int method1() {
int a = 10;
int b = 7;
int c = 0;
if (b >= a)
c++;
b = -47;
if (b > c)
c = b;
return c;
}
#答案是0
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-loops/index.html
第 10 單元:Java 集合
數組
#創建數組
int[] integers = new int[5];
int[] integers = new int[] { 1, 2, 3, 4, 5 };
int[] integers = { 1, 2, 3, 4, 5 };
int[] integers = new int[5];
for (int aa = 0; aa < integers.length; aa++) {
integers[aa] = aa+1;
}
裝箱與拆箱
#裝箱
int value = 238;
Integer boxedValue = Integer.valueOf(value);
#拆箱
Integer boxedValue = Integer.valueOf(238);
int intValue = boxedValue.intValue();
#自動裝箱和自動拆箱
int intValue = 238;
Integer boxedValue = intValue;
intValue = boxedValue;
#解析和轉換裝箱的類型
String characterNumeric = "238";
Integer convertedValue = Integer.parseInt(characterNumeric);
Integer boxedValue = Integer.valueOf(238);
String characterNumeric = boxedValue.toString();
列表
List 是一種有序集合,也稱為序列。因為 List 是有序的,所以您能夠完全控制項目進入 List 中的何處。Java List 集合只能包含對象(不能包含像 int 這樣的原語類型),而且它為其行為方式定義了嚴格的契約。
List 是一個接口,所以不能直接實例化它。這里將使用它的最常用實現 ArrayList。
#創建列表
List<String> listOfStrings = new ArrayList<String>();
List<String> listOfStrings = new ArrayList<>();
List<Integer> listOfIntegers = new ArrayList<>();
listOfIntegers.add(Integer.valueOf(238));
listOfIntegers.size()
listOfIntegers.get(0)
集(Set)
根據定義,Set 是一種包含唯一元素的集合結構 — 即沒有重復元素。List 可包含同一個對象數百次,而 Set 僅可包含某個特定實例一次。Java Set 集合僅可包含對象,而且它為它的行為方式定義了嚴格的契約。
因為 Set 是一個接口,所以不能直接實例化它。我最喜歡的實現之一是 HashSet,它很容易使用且類似于 List。
Set<Integer> setOfIntegers = new HashSet<Integer>();
setOfIntegers.add(Integer.valueOf(10));
映射(Map)
Map 是一種方便的集合構造,可以使用它將一個對象(鍵)與另一個對象(值)相關聯。您可能已想象到,Map 的鍵必須是唯一的,而且可在以后用于檢索值。Java Map 集合僅可包含對象,而且它為其行為方式定義了嚴格的契約。
因為 Map 是一個接口,所以不能直接實例化它。我最喜歡的實現之一是 HashMap。
Map<String, Integer> mapOfIntegers = new HashMap<>();
mapOfIntegers.put("1", Integer.valueOf(1));
Integer oneHundred68 = mapOfIntegers.get("168");
Set<String> keys = mapOfIntegers.keySet();
public void question5() {
int[] intArray = new int[4];
intArray[0] = 1;
intArray[1] = 2;
intArray[2] = Integer.valueOf(3);
intArray[3] = Integer.MAX_VALUE;
}
#該代碼沒有錯誤。通過自動拆箱,可將 Integer 對象賦給 int 數組。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-java-collections/index.html
第 11 單元:存檔 Java 代碼
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-archiving-java-code/index.html
第 12 單元:編寫良好的 Java 代碼
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-writing-good-java-code/index.html
第 13 單元:對象的后續處理
重載方法
創建兩個具有相同名稱和不同參數列表(即不同的參數數量或類型)的方法時,您就擁有了一個重載 方法。在運行時,JRE 基于傳遞給它的參數來決定調用您的重載方法的哪個變體。
在使用重載方法時,請記住兩條重要規則:
- 不能僅通過更改一個方法的返回類型來重載它。
- 不能擁有兩個具有相同名稱和相同參數列表的方法。
如果違背這些規則,編譯器就會拋出錯誤。
重寫方法
如果一個子類提供其父類中定義的方法的自有實現,這被稱為方法重寫。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-next-steps-with-objects/index.html
第 14 單元:異常
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-exceptions/index.html
第 15 單元:構建 Java 應用程序
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-building-java-applications/index.html
第 16 單元:繼承
Java 語言僅支持單一繼承,這意味著您只能對一個類使用 extends 關鍵字。所以任何 Java 類的類分層結構始終包含一直連接到 java.lang.Object 的一條直線。Java 語言支持在單個類中實現多個接口,為您提供單一繼承問題的解決辦法。
構造方法不是完整的面向對象成員,所以它們不是繼承的;必須在子類中顯式實現它們。
抽象化:兩條規則
作為一條經驗規則,不要在初始設計中抽象化。在設計過程的早期使用抽象類會迫使您進入一條可能限制您的應用程序的設計路線。您可以始終在繼承圖中的更高層級上重構常見行為(這是擁有抽象類的唯一理由) — 而且在發現您需要重構后再重構似乎總是更好一些。Eclipse 對重構提供了極好的支持。
第二,盡管抽象類很強大,仍要拒絕使用它們。除非您的超類包含大量相同的行為,而且這些超類本身沒有意義,否則保持它們非抽象化。較深的繼承圖可能使代碼維護變得很困難。請考慮太大的類與可維護的代碼之間的利弊。
更多詳情請見https://www.ibm.com/developerworks/cn/java/j-perry-inheritance/index.html
第 17 單元:接口
當您在應用程序中看到一組可分組到一起的常見行為,但它們存在兩個或多個實現時,可以考慮使用接口 定義該行為,這正是 Java 語言提供此特性的原因。但是,這個高級特性很容易被濫用、混淆和變成最討厭的形式,所以使用接口時需要小心謹慎。
以這種方式考慮接口可能有所幫助:它們像僅包含抽象方法的抽象類;它們僅定義契約,而不定義實現。
定義接口的語法
public interface InterfaceName {
returnType methodName(argumentList);
}
第 18 單元:嵌套類
嵌套類(或內部類) 是在一個類中定義的另一個類。
#公共嵌套類
public class Manager extends Employee {
public Manager() {
}
. . .
public class DirectReports {
. . .
}
}
// Meanwhile, in another method somewhere...
public static void main(String[] args) {
Manager manager = new Manager();
Manager.DirectReports dr = manager.new DirectReports();
}
#靜態內部類
public class Manager extends Employee {
public Manager() {
}
. . .
public static class DirectReports {
. . .
}
}
// Meanwhile, in another method somewhere...
public static void main(String[] args) {
Manager.DirectReports dr = new Manager.DirectReports();
}
第 19 單元:正則表達式
Regular Expressions API 有 3 個您幾乎總是在使用的核心類:
- Pattern 描述了一種字符串模式。
- Matcher 測試一個字符串,查看它是否與該模式匹配。
- PatternSyntaxException 告訴您,您嘗試定義的模式的某個方面無法被接受。
Pattern pattern = Pattern.compile("[Aa].*string");
Matcher matcher = pattern.matcher("A string");
boolean didMatch = matcher.matches();
int patternStartIndex = matcher.start();
int patternEndIndex = matcher.end();
while (matcher.find()) {
matcher.group();
}
String result = matcher.replaceAll("replacement");
第 20 單元:泛型
泛型是一種編譯器機制,您可通過該機制獲取通用的代碼并參數化(或模板化)剩余部分,從而以一種一般化方式創建(和使用)一些類型的實體(比如類或接口和方法)。這種編程方法被稱為泛型編程。
參數化的類:
List<Integer> listOfIntegers = new ArrayList<Integer>();
參數化的方法:
enum 類型:
enum 表示一組與某個特定概念相關的常量對象,每個對象都表示該集合中的一個不同的常量值。事實上,enum 非常像類,所以它們可擁有構造方法、屬性和方法。類與 enum 的一個區別是,enum 的構造方法必須聲明為 private,而且它無法擴展(或繼承)其他 enum。但是,一個 enum可以 實現一個接口。
public enum Gender {
MALE,
FEMALE,
OTHER
}
第 21 單元:I/O
import java.io.File;
File f = new File("temp.txt");
if (f.exists()) {
// File exists. Process it...
} else {
// File doesn't exist. Create it...
f.createNewFile();
}
字節流讀(InputStream 和子類)和寫(OutputStream 和子類)8 位字節。
字符流讀(Reader 和它的子類)和寫(Writer 和它的子類)16 位字符。
第 22 單元:Java 序列化
在序列化 的過程中,對象和它的元數據(比如對象的類名和它的屬性名稱)存儲為一種特殊的二進制格式。將對象存儲為這種格式(序列化 它)會保留所有必要的信息,使您在需要時能夠重建(或去序列化)對象。
對象序列化的兩個主要使用場景包括:
- 對象持久化:將對象的狀態存儲在一種永久的持久性機制中,比如數據庫
- 對象遠程存儲:將對象發送到另一臺計算機或另一個系統
實現序列化的第一步是使對象能夠使用該機制。您希望能夠序列化的每個對象必須實現一個名為 java.io.Serializable 的接口:
import java.io.Serializable;
public class Person implements Serializable {
// etc...
}
如果 Java 運行時嘗試序列化您的對象,無法序列化的對象的每個屬性會導致它拋出一個 NotSerializableException??梢允褂?transient 關鍵字管理此行為,告訴運行時不要嘗試序列化一些屬性。在這種情況下,您應該負責確?;謴瓦@些屬性(在必要時),以便您的對象能正常運行。