如果您喜歡該項目,請點擊。衷心歡迎您的貢獻。
多執行緒
收藏
Java 資料庫連線 (JDBC)
Java程式
Java 字串方法
雅加達伺服器頁面 (JSP)
小服務程序
Java多項選擇題
Java設計模式
休眠
Spring框架基礎知識
介紹
Java架構
Java 資料型別
Java 方法
Java函數式程式設計
Java Lambda 表達式
Java類
Java 建構函數
Java數組
Java 字串
Java反射
Java 串流
Java正規表示式
Java 檔案處理
Java異常
Java繼承
Java 方法重寫
Java多態性
Java抽象
Java介面
Java封裝
Java 泛型
各種各樣的
預設接口方法;
拉姆達表達式;
功能介面;
對方法和建構函數的引用;
可重複註釋
資料型別註釋;
方法參數的反射;
用於處理集合的 Stream API;
數組的並行排序;
用於處理日期和時間的新 API;
新的 JavaScript Nashorn 引擎;
新增了幾個用於線程安全操作的新類別;
新增了新的Calendar
和Locale
API;
新增了對 Unicode 6.2.0 的支援;
新增了用於使用 Base64 的標準類別;
增加了對無符號算術的支援;
改進了建構子java.lang.String(byte[], *)
和方法性能java.lang.String.getBytes()
;
新的AccessController.doPrivileged
實作可讓您設定權限子集,而無需檢查所有其他存取等級;
基於密碼的演算法變得更加穩健;
在 JSSE Server 中新增了對 SSL / TLS 伺服器名稱指示 (NSI) 的支援;
改進了密鑰庫(KeyStore);
新增SHA-224演算法;
刪除了 JDBC 橋 - ODBC;
刪除了 PermGen ,改變了類元資料的儲存方式;
能夠為 Java SE 平台建立設定文件,其中不包括整個平台,而是其中的一部分;
工具
新增了用於使用 JavaScript Nashorn 的實用程式jjs
;
命令java
可以運行JavaFX應用程式;
新增了用於分析 .class 檔案的實用程式jdeps
。
↥ 回到頂部
Nashorn是 Oracle 用 Java 開發的 JavaScript 引擎。旨在提供在 Java 應用程式中嵌入 JavaScript 程式碼的能力。與 Mozilla 基金會支援的 Rhino 相比,Nashorn 的效能提高了 2 到 10 倍,因為它直接在記憶體中編譯程式碼並將字節碼傳輸到 Java 虛擬機。 Nashorn 可以編譯 JavaScript 程式碼並產生使用特殊載入器載入的 Java 類別。也可以直接從 JavaScript 呼叫 Java 程式碼。
↥ 回到頂部
jjs
- 這是一個命令列實用程序,可讓您直接在控制台中執行 JavaScript 程式。
↥ 回到頂部
在 Java 中,可以透過三種不同的方式在命令列環境(控制台)中讀取使用者的輸入。
1.使用緩衝讀取器類別:
該方法透過將System.in(標準輸入流)包裝在InputStreamReader中來使用,而InputStreamReader又包裝在BufferedReader中,我們可以在命令列中讀取用戶的輸入。
/** * 緩衝讀取器類別*/import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Test { public static void main(String[] args) throws IOException { / / Enter使用 BufferReader 的資料 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); // 使用 readLine 讀取資料 String name = reader.readLine(); // 印出讀取的行 System.out.println(name); } }
2.使用Scanner類別:
Scanner 類別的主要用途是使用正規表示式解析原始類型和字串,但它也可用於在命令列中讀取使用者的輸入。
/** * Scanner 類別 */import java.util.Scanner;class GetInputFromUser { public static void main(String args[]) { // 使用 Scanner 從使用者取得輸入 Scanner in = new Scanner(System.in); String s = in.nextLine(); System.out.println("您輸入了字串" + s); int a = in.nextInt(); System.out.println("您輸入了整數" + a); 浮動 b = in.nextFloat(); System.out.println("您輸入的是 float " + b); } }
3.使用控制台類別:
它已成為從命令列讀取用戶輸入的首選方式。此外,它還可以用於讀取類似密碼的輸入,而不會回顯用戶輸入的字元;也可以使用格式字串語法(如 System.out.printf() )。
/** * Console 類別 */public class Sample { public static void main(String[] args) { // 使用 Console 輸入使用者資料 String name = System.console().readLine(); System.out.println(名稱); } }
↥ 回到頂部
javap指令顯示有關類別文件中存在的欄位、建構函式和方法的資訊。 javap 指令(也稱為 Java 反組譯器)反組譯一個或多個類別檔。
/** * Java 反組譯器 */class Simple { public static void main(String args[]) { System.out.println("Hello World"); } }
cmd> javap Simple.class
輸出
從“.java”編譯 class Simple { 簡單的(); 公共靜態無效主(java.lang.String []); }
↥ 回到頂部
System.out::println
表達式?指定的表達式說明了傳遞對println()
類別System.out
的靜態方法的參考。
↥ 回到頂部
流可以是順序的和並行的。對順序流的操作在一個處理器執行緒中執行,對並行流的操作則使用多個處理器執行緒。並行流透過靜態ForkJoinPool.commonPool()
方法使用共用流ForkJoinPool
。在這種情況下,如果環境不是多核,則流將按順序執行。事實上,並行流的使用被簡化為這樣的事實:流中的資料將被分成多個部分,每個部分在一個單獨的處理器核心上進行處理,最後這些部分被連接起來,並進行最終的操作他們。
您也可以使用parallelStream()
介面方法從集合Collection
建立並行流。
若要讓常規順序流並行,您必須呼叫物件parallel()
上的Stream
方法。 isParallel()
方法可讓您確定流是否是並行的。
使用方法parallel()
和sequential()
可以決定哪些運算可以並行,哪些只能順序運算。您也可以從任何順序流建立並行流,反之亦然:
收藏 。 .peek(...) // 操作是順序的 。 .map(...) // 該操作可以並行執行, .sequential() .reduce ( ... ) // 操作再次依序進行
通常,元素會按照它們在資料來源中定義的順序傳輸到流。使用並行流時,系統會保留元素的順序。一個例外是forEach()
方法,它可以以隨機順序輸出元素。為了保持順序,需要應用forEachOrdered()
方法。
可能影響並行流性能的標準:
資料大小 - 資料越多,首先將資料分離,然後將它們組合起來就越困難。
處理器核心的數量。理論上,電腦的核心越多,程式運作的速度就越快。如果機器只有一個核心,那麼使用並行執行緒就沒有意義。
流使用的資料結構越簡單,操作速度就越快。例如, ArrayList
中的資料很容易使用,因為該集合的結構假定了一系列不相關的資料。但類型集合LinkedList
並不是最佳選擇,因為在順序清單中,所有元素都與上一個/下一個元素連接。而且這樣的數據很難並行化。
使用原始類型的操作將比使用類別物件的操作更快。
強烈建議您不要將並行流用於任何長時間操作(例如網絡連接),因為所有並行流都與一個ForkJoinPool
一起工作,這樣的長時間操作可能會由於缺乏可用線程而停止 JVM 中的所有並行流在游泳池等處。並行流應僅用於計數為毫秒的短操作,但不適用於計數為秒和分鐘的操作;
在並行流中保存順序會增加執行成本,如果順序不重要,可以停用其保存,從而透過使用中間操作unordered()
來提高生產率:
集合.parallelStream() .sorted() .無序() .collect(Collectors.toList());
↥ 回到頂部
Java虛擬機器(JVM)是一種提供執行時間環境的規範,可以在其中執行java字節碼(.class檔案)。 JVM 是平台。 JVM 充當「虛擬」機器或處理器。 Java 的平台獨立性主要由其 Java 虛擬機器 (JVM) 組成。 JVM 使這成為可能,因為它了解特定的指令長度和平台(作業系統)的其他特殊性。
JVM 不是獨立於平台的。 Java虛擬機器(JVM)提供了執行java檔案(.class檔案)的環境。所以最終它取決於內核,而內核因作業系統(作業系統)而異。 JVM 用於將字節碼翻譯成特定電腦的機器語言,並實際執行對應的機器語言指令。
↥ 回到頂部
即時 (JIT) 編譯器是運行時環境的一個元件,它透過在運行時將字節碼編譯為本機機器碼來提高 Java 應用程式的效能。
Java 程式由類別組成,類別包含與平台無關的字節碼,可以由許多不同電腦體系結構上的 JVM 來解釋。在運行時,JVM 會載入類別文件,確定每個字節碼的語義,並執行適當的計算。解釋期間額外的處理器和記憶體使用量意味著 Java 應用程式的執行速度比本機應用程式慢。 JIT 編譯器透過在執行時間將字節碼編譯為本機機器碼來幫助提高 Java 程式的效能。 JIT 編譯器預設為啟用。當一個方法被編譯後,JVM 直接呼叫該方法的編譯程式碼,而不是解釋它。
↥ 回到頂部
Java 類別載入器是 Java 執行時間環境的一部分,它將 Java 類別動態載入到 Java 虛擬機器中。 Java程式碼透過javac編譯器編譯成class文件,JVM透過執行class檔案中所寫的字節碼來執行Java程式。 ClassLoader 負責從檔案系統、網路或任何其他來源載入類別檔案。
類別載入器的類型:
1.引導類別載入器:
它從 rt.jar 和其他核心類別載入標準 JDK 類別檔案。它從 jre/lib/rt.jar 載入類別文件。例如java.lang套件類別。
2.擴充類別載入器:
它直接從 JDK 擴充載入類,通常是JAVA_HOME/lib/ext
目錄或任何其他目錄(如 java.ext.dirs)。
3.系統類別載入器:
它從 CLASSPATH 環境變數載入應用程式特定的類別。可以在使用 -cp 或類路徑命令列選項呼叫程式時設定它。
↥ 回到頂部
1.JDK :
Java開發工具包是Java環境的核心元件,提供編譯、偵錯和執行Java程式所需的所有工具、執行檔和二進位。
2. JVM :
JVM 負責將位元組代碼轉換為機器特定代碼。 JVM 也依賴平台,並提供核心 Java 功能,如記憶體管理、垃圾收集、安全性等。 JVM之所以被稱為虛擬,是因為它提供了不依賴底層作業系統和機器硬體的介面。
2.JRE :
Java運行環境提供了執行java程式的平台。 JRE 由 JVM 和 java 二進位檔案以及其他類別組成,可以成功執行任何程式。
↥ 回到頂部
1.Java堆空間:
Java 執行時期使用 Java 堆空間為物件和JRE 類別分配記憶體。每當我們創建任何物件時,它總是在堆空間中創建。
垃圾收集在堆記憶體上運行,以釋放沒有任何引用的物件使用的記憶體。在堆空間中建立的任何物件都具有全域存取權限,並且可以從應用程式的任何位置引用。
2.Java堆疊記憶體:
java中的堆疊是一段內存,其中包含方法、局部變數和引用變數。局部變數是在堆疊中創建的。
堆疊記憶體始終按 LIFO(後進先出)順序引用。每當呼叫一個方法時,都會在堆疊記憶體中建立一個新區塊,以便該方法保存本地原始值並引用該方法中的其他物件。
一旦方法結束,該區塊就會變得未使用並可用於下一個方法。與堆疊記憶體相比,堆疊記憶體大小非常小。
不同之處:
範圍 | 堆疊記憶體 | 堆疊空間 |
---|---|---|
應用 | 堆疊是分部分使用的,在執行緒執行期間一次使用一個 | 整個應用程式在運行時使用堆空間 |
尺寸 | 堆疊具有大小限制,取決於作業系統,通常小於堆 | 堆沒有大小限制 |
貯存 | 僅儲存原始變數和對在堆空間中建立的物件的引用 | 所有新建立的物件都儲存在這裡 |
命令 | 使用後進先出 (LIFO) 記憶體分配系統對其進行訪問 | 該記憶體透過複雜的記憶體管理技術進行訪問,包括年輕代、老一代或終身代以及永久代。 |
生活 | 堆疊記憶體僅在當前方法運行時存在 | 只要應用程式運行,堆空間就存在 |
效率 | 與堆相比,分配速度相對快得多 | 與堆疊相比,分配速度較慢 |
分配/解除分配 | 當方法被呼叫和返回時,該記憶體會自動分配和釋放 | 堆空間在新物件建立時分配,並在不再被引用時由 Gargabe Collector 釋放 |
↥ 回到頂部
JVM 是一個接受 Java 字節碼並將字節碼(逐行)轉換為機器可理解的程式碼的程式。 JVM 執行一些特定類型的操作:
程式碼載入
驗證碼
執行程式碼
它為用戶提供運行時環境
JVM分配的記憶體區域類型:
1. 類別載入器:類別載入器是JVM的子系統,用來載入類別檔案。
2. 類別(方法)區: 類別(方法)區儲存每個類別的結構,例如執行時間常數池、欄位和方法資料、方法的程式碼。
3. 堆:是分配物件的運行時資料區域。
4. 堆疊:Java 堆疊儲存幀。每個執行緒都有一個私有的 JVM 堆疊,與執行緒同時建立。
5. 程式計數器暫存器:PC(程式計數器)暫存器。它包含目前正在執行的Java虛擬機器指令的位址。
6. 本機方法堆疊:它包含應用程式中使用的所有本機方法。
↥ 回到頂部
將原始資料類型自動轉換為其等效的包裝類型稱為裝箱,相反的操作稱為拆箱。
範例:自動裝箱
/** * 自動裝箱 */class BoxingExample { public static void main(String args[]) { int a = 50; 整數a2 = new Integer(a); // 裝箱整數 a3 = 5; // 拳擊 System.out.println(a2 + " " + a3); } }
例:拆箱
/** * 拆箱 */class UnboxingExample { public static void main(String args[]) { Integer i = new Integer(50); } int a = i; System.out.println(a); } }
↥ 回到頂部
1. 瞬態:
瞬態修飾符告訴Java物件序列化子系統在序列化類別的實例時排除該欄位。當物件被反序列化時,該欄位將被初始化為預設值;即引用型別為 null,原始型別為零或 false。
例子:
/** * 瞬態 */public瞬態 int limit = 55; // 不會持久 public int b; // 將持續存在
2. 揮發性:
易失性修飾符告訴 JVM,寫入字段應始終同步刷新到內存,並且讀取字段應始終從內存讀取。這意味著可以在多執行緒應用程式中安全地存取和更新標記為易失性的字段,而無需使用本機或基於標準庫的同步。
例子:
/** * 易失性 */public class MyRunnable 實作 Runnable { private volatile boolean active; 公共無效運行(){活動=真; 同時(活動){ } } 公共無效停止(){ 活動=假; } }
↥ 回到頂部
斷言允許測試程序中所做的任何假設的正確性。斷言是使用Java中的assert語句來實現的。
在執行斷言時,它被認為是真的。如果失敗,JVM 會拋出一個名為AssertionError
的錯誤。它主要用於開發過程中的測試目的。
斷言語句與布林表達式一起使用,可以用兩種不同的方式編寫。
// 第一種方式斷言表達式; // 第二種方式斷言表達式1 : 表達式2;
例子:
/** * 斷言 */public class 範例 { public static void main(String[] args) { int Age = 14; 斷言年齡 <= 18 :「不能投票」; System.out.println("選民年齡為" + 年齡); } }
↥ 回到頂部
1.最終變數:
最終變數只不過是常數。一旦final變數被初始化,我們就無法改變它的值。
例子:
/** * 最終變數 */class Demo { Final int MAX_VALUE = 99; 無效 myMethod() { MAX_VALUE = 101; } public static void main(String args[]) { 示範 obj = new Demo(); obj.myMethod(); } }
輸出
線程“main”java.lang.Error 中出現異常:未解決的編譯問題: 最後一個欄位 Demo.MAX_VALUE 無法指派在 Beginnersbook.com.Demo.myMethod(Details.java:6) 和 Beginnersbook.com.Demo.main(Details.java:10)
2. 空白最終變數:
在宣告時未初始化的最終變數稱為空白最終變數。我們必須在類別的建構子中初始化空白的最終變量,否則會拋出編譯錯誤(錯誤: variable MAX_VALUE might not have been initialized
)。
例子:
/** * 空白最終變數 */class Demo { // 空白最終變數 Final int MAX_VALUE; Demo() { // 必須在建構子中初始化 MAX_VALUE = 100; } void myMethod() { System.out.println(MAX_VALUE); } public static void main(String args[]) { 示範 obj = new Demo(); obj.myMethod(); } }
輸出
100
3.最終方法:
最終方法不能被重寫。這意味著即使子類別可以毫無問題地呼叫父類別的final方法,但它不能覆寫它。
例子:
/** * 最終方法 */class XYZ { Final void demo() { System.out.println("XYZ 類別方法"); } }class ABC extends XYZ { void demo() { System.out.println("ABC 類別方法"); } public static void main(String args[]) { ABC obj = new ABC(); obj.demo(); } }
↥ 回到頂部
如果將原始類型或字串定義為常數且其值在編譯時已知,則編譯器會將程式碼中各處的常數名稱替換為其值。這稱為編譯時常數。
編譯時間常數必須是:
宣布最終
原語或字串
在聲明內初始化
用常數表達式初始化
它們在編譯時被替換為實際值,因為編譯器預先知道它們的值並且也知道它在運行時不能更改。
私有最終 int x = 10;
↥ 回到頂部
存取說明符/修飾符有助於限制類別、建構子、變數、方法或資料成員的範圍。
java中有四種類型的存取修飾符:
default
– 不需要關鍵字,當在沒有任何存取說明符的情況下聲明類別、建構子、變數、方法或資料成員時,它具有預設存取範圍,即只能在同一包內存取。
private
- 當宣告為 private 時,存取範圍僅限於封閉類別內。
protected
- 當宣告為協定時,存取範圍僅限於封閉類別、相同套件以及其他套件中的子類別。
public
- 當聲明為公共時,可以在程式中的任何地方存取。
... /* 資料成員變數 */ String firstName="Pradeep"; /* 預設範圍 */ protected isValid=true; /* 保護範圍 */ private String otp="AB0392"; /* 私有範圍 */ public int id = 12334; /* 公共範圍 */ … ... /* 資料成員函數 */ String getFirstName(){ return this.firstName; } /* 預設作用域*/ protected boolean getStatus(){this.isValid;} /* 受保護作用域*/ private voidgenerateOtp(){ /* 私人作用域*/ this.otp = this.hashCode() << 16; }; 公用 int getId(){ 回傳 this.id; } /* 公共範圍 */ … .../* 內部類別*/ class A{} /* 預設作用域*/ protected class B{} /* 受保護作用域*/ private class C{} /* private 作用域*/ public class D{} /* public 作用域*/ …
↥ 回到頂部
在Java中,所有非靜態方法預設都是虛擬函數。只有用關鍵字final
標記的方法(不能被重寫)以及private methods
(不能繼承)才是非虛擬的。
範例:帶接口的虛擬函數
/** * 函數 applyBrakes() 是虛擬的,因為 * 介面中的函數被設計為可以被重寫。 **/介面自行車 { void applyBrakes(); }class ACMEBicycle Implements Bicycle { public void applyBrakes() { // 這裡我們實作 applyBrakes() System.out.println("Brakes Applied"); // 功能 } }
↥ 回到頂部
本機方法是一種 Java 方法(實例方法或類別方法),其實作也是用另一種程式語言(例如 C/C++)編寫的。此外,標記為本機的方法不能有主體,並且應以分號結尾:
主要.java:
公用類別 Main { 公用本機 int intMethod(int i); 公共靜態無效主(字串[] args){ System.loadLibrary(“主”); System.out.println(new Main().intMethod(2)); } }
主要.c:
#include <jni.h>#include "Main.h"JNIEXPORT jint JNICALL Java_Main_intMethod( JNIEnv *env, jobject obj, jint i) { return i * i; } }
編譯並運行:
javac Main.javajavah -jni Maingcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux Main.cjava -Djava.library.path=.主要的
輸出
4
↥ 回到頂部
如果一個方法被宣告為靜態,那麼它就是一個類別的成員,而不是屬於該類別的物件。無需創建該類別的物件即可呼叫它。靜態方法還具有存取類別的靜態資料成員的能力。
靜態方法有一些限制
靜態方法不能使用非靜態資料成員或直接呼叫非靜態方法。
this
和super
不能在靜態上下文中使用。
靜態方法只能存取靜態類型資料(靜態類型實例變數)。
無需建立類別的物件來呼叫靜態方法。
靜態方法不能在子類別中被重寫
例子:
/** * 靜態方法 */class Parent { static void display() { System.out.println("Super class"); } }public class Example extends Parent { void display() // 試著重寫 display() { System.out.println("Sub class"); } 公共靜態無效主(字串[] args){ 父物件 = new 範例(); obj.display(); } }
這會產生編譯時錯誤。輸出如下 -
Example.java:10: 錯誤:Example 中的 display() 無法覆寫 Parentvoid display() 中的 display() // 嘗試覆寫 display() ^重寫的方法是靜態的1錯誤
↥ 回到頂部
使用 lambda 表達式的結構和特徵是什麼? lambda 是一組指令,可以分成單獨的變量,然後在程式的各個位置重複呼叫。
lambda 表達式的基礎是lambda 運算符,它代表箭頭->
。此運算子將 lambda 表達式分為兩部分:左側包含表達式參數列表,右側實際上表示 lambda 表達式的主體,其中執行所有操作。
lambda 表達式本身並非執行,而是形成函數式介面中定義的方法的實作。重要的是,函數式介面應該只包含一個沒有實作的方法。
介面可操作 { int 計算 ( int x , int y ); }public static void main(String[] args) { 可操作的操作 = (x, y) -> x + y; int 結果 = 操作.calculate ( 10 , 20 ); System.out.println(結果); // 30 }
事實上,lambda 表達式在某種程度上是以前在 Java 中使用的內部匿名類別的簡寫形式。
延遲執行 lambda 表達式- 它在程式的一個位置定義一次,如有必要,可以在程式的任何位置呼叫任意次數。
lambda 表達式的參數在類型上必須與函數式介面方法的參數相對應:
operation = ( int x, int y) -> x + y;// 寫 lambda 表達式本身時,允許不指定參數類型: (x, y) -> x + y;// 如果方法不接受任何參數,則寫空括號,例如: () -> 30 + 20 ; // 如果方法只接受一個參數,則括號可以省略: n - > n * n;
尾隨 lambda 表達式不需要傳回任何值。
介面 Printable { void print( String s ); } public static void main ( String[] args) { 可列印印表機 = s -> System.out.println(s); 印表機.print(“你好,世界”); }// _ 區塊 lambda - 表達式_ 用大括號括起來。模組化 lambda 表達式可以在嵌套區塊、循環、「設計 if」、「switch 語句」、建立變數等中使用。 d.如果您封鎖 lambda - 表達式必須傳回一個值,則它明確地套用 `statement return statements' : 可操作的操作 = ( int x, int y) - > { if (y == 0) { 回傳 0 ; } else { 回傳 x / y; } };
將 lambda 表達式作為方法參數傳遞
介面條件 { boolean isAppropriate ( int n ); }private static int sum ( int [] 數字, Condition 條件) { int result = 0 ; for ( int i : 數字) { if (condition.isAppropriate(i)) { 結果 + = i; } 返回結果; }public static void main ( String [] args) { System.out.println(sum ( new int [] { 0 , 1 , 0 , 3 , 0 , 5 , 0 , 7 , 0 , 9 }, (n) - > n ! = 0 )); }
↥ 回到頂部
從 lambda 表達式存取外部作用域變數與從匿名物件存取非常相似。
不可變(實際上是最終的 - 不一定標記為最終)局部變數;
類別字段
靜態變數。
不允許在 lambda 表達式內部存取已實現的功能介面的預設方法。
↥ 回到頂部
如果類別中存在的方法已經做了所有必要的事情,那麼你可以使用方法引用機制(methodreference)來直接傳遞這個方法。結果將與定義呼叫此方法的 lambda 表達式的情況完全相同。
例子:
私有介面 Measurable { public int length(String string); }public static void main ( String[] args) { 可測量 a = String::length; System.out.println(a.length("abc")); }
方法參考可能比使用 lambda 表達式更有效。此外,它們還為編譯器提供了有關類型的更好信息,如果您可以在使用現有方法的引用和使用 lambda 表達式之間進行選擇,則應始終使用方法引用。
↥ 回到頂部
關於靜態方法;
每個實例方法;
到構造函數。
↥ 回到頂部
嵌套內部類別可以存取外部類別的任何私有實例變數。與任何其他實例變數一樣,我們可以使用存取修飾符 private、protected、public 和 default 修飾符。
例子:
/** * 內部類別 */類別外部 { 類別內部{ 公共無效顯示(){ System.out.println("在巢狀類別方法中"); } } } 類別主要{ 公共靜態無效主(字串[] args){ Outer.Inner in = new Outer().new Inner(); 在.show(); } }
子類別是從超類別繼承一個或多個方法的類別。
例子:
/** * 子類別 */class Car { //...} HybridCar 類別擴展了 Car { //...}
↥ 回到頂部
1.靜態類別載入:
使用new
關鍵字建立物件和實例稱為靜態類別載入。類別定義的檢索和物件的實例化是在編譯時完成的。
例子:
/** * 靜態類別載入 */class TestClass { public static void main(String args[]) { TestClass tc = new TestClass(); } }
2.動態類別載入:
載入類別使用Class.forName()
方法。當編譯時不知道類別的名稱時,會進行動態類別載入。
例子:
/** * 動態類別載入 */Class.forName(String className);
↥ 回到頂部
1.運行時類別:
java.lang.Runtime類別是Object類別的子類,提供對Java執行時間系統的存取。運行時信息,如內存可用性、調用垃圾收集器等。
例子:
/** * 執行時期類別 */public class RuntimeTest { static class Message extends Thread { public void run() { System.out.println(" Exit"); } } } public static void main(String[] args) { try { Runtime.getRuntime().addShutdownHook(new Message()); } System.out.println("程式開始..."); System.out.println("請等待5秒..."); 線程.sleep(5000); System.out.println("程式結束..."); } catch (Exception e) { e.printStackTrace(); } } }
2.系統類:
System 類別的目的是提供對系統資源的存取。它包含對標準輸入、標準輸出、錯誤輸出流、當前時間(以毫秒為單位)、終止應用程式等的存取。
↥ 回到頂部
1.使用new關鍵字:
MyObject 物件 = new MyObject();
2.使用Class.forName():
MyObject 物件 = (MyObject) Class.forName("subin.rnd.MyObject").newInstance();
3.使用clone():
MyObject anotherObject = new MyObject();MyObject object = (MyObject) anotherObject.clone();
4.使用物件反序列化:
ObjectInputStream inStream = new ObjectInputStream(anInputStream );MyObject 物件 = (MyObject) inStream.readObject();
↥ 回到頂部
不可變物件是不會改變的物件。 Java 不可變物件的所有欄位必須是內部私有最終欄位。它不得實現任何設定器。它需要一個為每個字段獲取值的建構函數。
建立不可變物件:
不要添加任何setter方法
聲明所有字段為最終字段和私有字段
如果欄位是可變對象,則為 getter 方法建立它的防禦性副本
如果傳遞給建構函數的可變物件必須指派給一個字段,則建立它的防禦性副本
不允許子類別重寫方法。
/** * 不可變物件 */public class DateContainer { private Final Date date; 公用 DateContainer() { this.date = new Date(); } public Date getDate() { return new Date(date.getTime()); } }
↥ 回到頂部
不可變類別意味著一旦創建了對象,我們就無法更改其內容。在 Java 中,所有包裝類別(如 Integer、Boolean、Byte、Short)和 String 類別都是不可變的。
建立不可變類別的規則:
該類別必須聲明為最終類
類別中的資料成員必須宣告為final
參數化建構函數
裡面所有變數的Getter方法
沒有二傳手
/** * 不可變類別 */public Final class Employee { Final String pancardNumber; public Employee(String pancardNumber) { this.pancardNumber = pancardNumber; } } public String getPancardNumber() { return pancardNumber; } } }
↥ 回到頂部
Bootstrap ClassLoader 負責從rt.jar載入標準 JDK 類別文件,它是 java 中所有類別載入器的父級。 Java中內建的ClassLoader分為三種:
1. Bootstrap類載入器:載入JDK內部類,通常載入rt.jar和其他核心類例如java.lang.*包類
2.擴充類別載入器:它從JDK擴充目錄載入類,通常是$JAVA_HOME/lib/ext目錄。
3. 系統類別載入器:它從目前類別路徑載入類,可以在使用 -cp 或 -classpath 命令列選項呼叫程式時設定該類路徑。
/** * ClassLoader */import java.util.logging.Level;import java.util.logging.Logger;public class ClassLoaderTest { public static void main(String args[]) { try { // 印出該類別 System 的 ClassLoader main(String args[]) { try { // 印出該類別 System 的 ClassLoader .out.println("類別載入器:" + ClassLoaderTest.class.getClassLoader()); // 嘗試使用擴充類別載入器再次明確載入這類 Class.forName("Explicitly load class", true, ClassLoaderTest.class.getClassLoader().getParent()); } catch (ClassNotFoundException ex) { Logger.getLogger(ClassLoaderTest.class.getName()).log(Level.SEVERE, null, ex); } } }
↥ 回到頂部
在 Java 中建立物件的不同方法
使用新關鍵字:
類別 ObjectCreationExample{String 所有者; }public class MainClass {public static void main(String[] args) {// 這裡我們使用 new keywordsObjectCreationExample 建立 JBT 物件 obj = new ObjectCreationExample(); } }
使用新實例(反射)
類別 CreateObjectClass {static int j = 10;CreateObjectClass() {i = j++; }int i;@Overridepublic String toString() {return "i 的值:" + i; } }class MainClass {public static void main(String[] args) {try {Class cls = Class.forName("CreateObjectClass");CreateObjectClass obj = (CreateObjectClass) cls.newInstance();CreateObjectClass obj1 = (CreateObjectClass) cls.newInstance();CreateObjectClass obj1 = (CreateObjectClass) clreate.new. ();System.out.println(obj);System.out.println(obj1); } catch (ClassNotFoundException e) {e.printStackTrace(); } catch (InstantiationException e) {e.printStackTrace(); } catch (IllegalAccessException e) {e.printStackTrace(); } } }
使用克隆:
類別 CreateObjectWithClone 實作 Cloneable {@Overrideprotected Object clone() 拋出 CloneNotSupportedException {return super.clone(); }int i;static int j = 10;CreateObjectWithClone() {i = j++; }@Overridepublic String toString() {return "i 的值:" + i; } }class MainClass {public static void main(String[] args) {CreateObjectWithClone obj1 = new CreateObjectWithClone();System.out.println(obj1);try {CreateObjectWithClone obj2 = (CreateObjectWithClun); println(obj2); } catch (CloneNotSupportedException e) {e.printStackTrace(); } } }
使用類別載入器
類別 CreateObjectWithClassLoader {static int j = 10;CreateObjectWithClassLoader() {i = j++; }int i;@Overridepublic String toString() {return "i 的值:" + i; } }public class MainClass {public static void main(String[] args) {CreateObjectWithClassLoader obj = null;try {obj = (CreateObjectWithClassLoader) new MainClass().getClass() .getClassLoader().loadClass("CreateObjectWithClassLoader").newInstance(); // 應使用完全限定的類別名稱。 } catch (InstantiationException e) {e.printStackTrace(); } catch (IllegalAccessException e) {e.printStackTrace(); } catch (ClassNotFoundException e) {e.printStackTrace(); }System.out.println(obj); } }
↥ 回到頂部
Object類別預設是java中所有類別的父類別。
方法 | 描述 |
---|---|
公共最終類別 getClass() | 傳回該物件的Class類別物件。 Class類別也可以用來取得該類別的元資料。 |
公共 int hashCode() | 傳回該物件的雜湊碼編號。 |
公共布爾等於(對象 obj) | 將給定物件與此物件進行比較。 |
受保護的物件克隆()拋出CloneNotSupportedException | 建立並傳回該物件的精確副本(克隆)。 |
公有字串 toString() | 傳回該物件的字串表示形式。 |
公共最終無效通知() | 喚醒單一線程,等待該物件的監視器。 |
公共最終無效notifyAll() | 喚醒所有等待該物件監視器的執行緒。 |
公共最終無效等待(長時間超時)拋出InterruptedException | 導致目前執行緒等待指定的毫秒,直到另一個執行緒通知(呼叫notify() 或notifyAll() 方法)。 |
公共最終無效等待(長逾時,int nanos)拋出InterruptedException | 導致目前執行緒等待指定的毫秒和奈秒,直到另一個執行緒通知(呼叫notify() 或notifyAll() 方法)。 |
公用最終無效等待()拋出InterruptedException | 導致目前執行緒等待,直到另一個執行緒通知(呼叫notify() 或notifyAll() 方法)。 |
protected void Finalize() 拋出 Throwable | 在物件被垃圾收集之前由垃圾收集器呼叫。 |
↥ 回到頂部
可選值Optional
是一個物件的容器,該物件可能包含也可能不包含值null
。這樣的包裝紙是一種方便的預防手段