這段時間學習了很多知識,好多還有疑問不清楚的地方。今天有空總結一下。
javame,javase,javaee
一、Java ME(Micro Edition,微型版)
Java ME是一種適用于移動設備和嵌入式系統的小型Java平臺,具有高度可移植性和跨平臺性,并提供豐富的API庫和工具來簡化應用程序開發。比如在按鍵機里的java小游戲。隨著智能手機(iOS/Android)的普及,Java ME 逐漸被淘汰。
二、Java SE(Standard Edition,標準版)
Java 的基礎版本,面向桌面應用和通用軟件開發,是其他 Java 版本的基礎。包含 Java 核心類庫(如?java.lang
、java.util
、java.io
?等)、圖形界面工具包(Swing/AWT)、網絡編程(Socket)等。開發工具:IntelliJ IDEA、Eclipse、NetBeans。持續更新,是 Java 生態的基石。
-
技術棧:
- 核心技術:多線程、IO/NIO、反射、集合框架、JDBC(數據庫連接)等。
- 開發工具:IntelliJ IDEA、Eclipse、NetBeans。
?三、Java EE(Enterprise Edition,企業版)→ 現更名為?Jakarta EE
原由 Oracle 主導,用于開發大型企業級應用(如分布式系統、Web 服務、電商平臺、金融系統等)。基于 Java SE,提供一套企業級開發規范(如 Servlet、JSP、EJB、JPA、JMS、WebSocket 等),解決分布式事務、安全性、高并發等復雜場景問題。
技術棧(Jakarta EE 核心規范):
- Web 層:Servlet、Jakarta Server Pages(JSP)、Jakarta Faces(JSF)、WebSocket。
- 業務層:Enterprise JavaBeans(EJB)、CDI(上下文和依賴注入)。
- 數據層:JPA(Java Persistence API,ORM 規范)、JDBC。
- 分布式與集成:JMS(消息隊列)、JAX-RS(RESTful Web 服務)、JAXB(XML 綁定)。
- 容器支持:需要運行在應用服務器中(如 Tomcat、WildFly、GlassFish、WebSphere、WebLogic)。
三者對比
維度 | Java ME | Java SE | Jakarta EE(原 Java EE) |
---|---|---|---|
目標場景 | 嵌入式設備、移動設備(舊) | 桌面應用、控制臺程序 | 企業級應用(Web、分布式系統) |
依賴關系 | 基于 Java SE 精簡 | 基礎版本 | 基于 Java SE,擴展企業功能 |
核心技術 | MIDP、CLDC、移動圖形庫 | 核心類庫、Swing/AWT | Servlet、JPA、EJB、JMS 等規范 |
運行環境 | 小型設備虛擬機(KVM) | 標準 JVM | 應用服務器(如 Tomcat、WildFly) |
現狀 | 已淘汰,僅遺留系統 | 持續更新,生態核心 | 轉型云原生,標準化企業開發 |
javac?
javac
?是 Java 編譯器,用于將 Java 源代碼(.java
?文件)編譯為字節碼(.class
?文件),以便在 Java 虛擬機(JVM)上運行。它是?Java Development Kit (JDK)?的核心組件之一。
jdk版本 8 ,16,17,21
版本 | 發布時間 | 特性亮點 | 支持狀態 | 適用場景 |
---|---|---|---|---|
JDK 8 | 2014-03 | Lambda 表達式、Stream API、日期 API | LTS(長期支持至 2030-12) | legacy 系統、穩定性優先的企業應用 |
JDK 16 | 2021-03 | 模式匹配、Record 類、Vector API | 非 LTS(支持至 2022-09) | 嘗鮮新特性,不建議生產環境 |
JDK 17 | 2021-09 | 密封類、強封裝 JDK 內部 API | LTS(長期支持至 2029-09) | 企業級應用、云原生開發 |
JDK 21 | 2023-09 | 虛擬線程、分代 ZGC、字符串模板 | LTS(長期支持至 2031-09) | 高性能、高并發應用 |
jdk目錄
jdk-<版本號>/
├── bin/ # 可執行程序(開發工具)
├── conf/ # 配置文件
├── include/ # C/C++ 頭文件(用于JNI開發)
├── jmods/ # JMOD 模塊文件(Java 9+ 模塊化系統)
├── legal/ # 許可證文件
├── lib/ # 工具庫文件
└── release # JDK 版本信息
1.?bin/
?- 開發工具
包含編譯器、調試器、運行工具等可執行程序:
javac
:Java 編譯器,將?.java
?源碼編譯為?.class
?字節碼。java
:Java 應用程序啟動器,運行?.class
?或 JAR 文件。jar
:JAR 文件打包工具,用于創建和管理 JAR 歸檔。jdb
:Java 調試器,用于調試 Java 程序。javadoc
:文檔生成工具,從源碼注釋生成 API 文檔。jconsole
:可視化監控工具,查看 JVM 性能和資源使用。jlink
:Java 9+ 新增,用于創建自定義運行時鏡像。jmod
:Java 9+ 新增,操作 JMOD 模塊文件。
2.?conf/
?- 配置文件
存放 JDK 和 JRE 的配置:
security/
:安全相關配置(如?java.security
)。logging.properties
:Java 日志系統配置。net.properties
:網絡相關配置(如代理設置)。
3.?include/
?- C/C++ 頭文件
用于?JNI(Java Native Interface)?開發,允許 Java 調用本地 C/C++ 代碼:
jni.h
:JNI 核心頭文件。jni_md.h
:平臺相關的 JNI 頭文件(如 Windows/macOS/Linux 不同實現)。
4.?jmods/
?- JMOD 模塊文件(Java 9+)
Java 9 引入的模塊化系統,每個?.jmod
?文件包含:
- 模塊的類文件、資源、配置。
- 模塊描述符?
module-info.class
。 - 本地庫和命令行工具(如?
java.base.jmod
)。
5.?lib/
?- 庫文件
存放 JDK 工具依賴的庫和資源:
tools.jar
:開發工具(如?javac
)的實現類。jrt-fs.jar
:Java 運行時文件系統,用于訪問 JMOD 文件。src.zip
:Java 標準庫的源代碼(如?java.util
、java.io
)。jvm.cfg
:JVM 配置文件,指定可用的 JVM 實現。
6.?legal/
?- 許可證文件
包含各模塊的開源許可證信息(如?java.base
?的許可證)。
7.?release
?- JDK 版本信息
文本文件,記錄 JDK 版本、構建信息和依賴關系:
編輯環境變量為什么分兩步先配置java_HOME 再配置path
統一引用:??PATH中的路徑一般不進行修改。
若直接在?PATH
?中寫死 JDK 路徑(如?C:\Program Files\Java\jdk-17\bin
),當需要切換 JDK 版本時,需同時修改?PATH
?中的所有路徑,容易出錯。?
靈活切換版本:通過修改?JAVA_HOME
?的值,無需改動?PATH
,即可快速切換 JDK 版本。
String,StringBUffer,StringBuilder
String
?類是 Java 語言的核心類之一,位于?java.lang
?包?下。該包是 Java 語言的基礎,無需顯式導入即可直接使用。StringBuffer
?和?StringBuilder
?是 Java 中用于?高效處理可變字符串?的類,它們彌補了?String
?類不可變的缺陷。
特性 | StringBuffer | StringBuilder |
---|---|---|
線程安全 | 同步(所有方法有?synchronized ) | 非同步(性能更高) |
誕生版本 | JDK 1.0 | JDK 1.5(為優化 StringBuffer 引入) |
適用場景 | 多線程環境(如 Web 應用) | 單線程環境(如工具類、局部變量) |
性能 | 略低(同步開銷) | 更高(無同步開銷) |
共同特性
-
可變字符串:
與?String
?不同,StringBuffer
?和?StringBuilder
?的內容可動態修改,無需創建新對象。 -
相同 API:
兩者方法簽名幾乎完全一致,
append() // 追加內容
insert() // 插入內容
delete() // 刪除指定位置字符
replace() // 替換字符
reverse() // 反轉字符串
capacity() // 獲取容量(非長度)
ensureCapacity() // 確保容量至少為指定值
注釋
單行注釋、多行注釋?和?文檔注釋
一、單行注釋(//)
- 語法:以?
//
?開頭,直到行末結束。 - 用途:解釋單行代碼或添加簡短說明。
二、多行注釋(/* ... */)
- 語法:以?
/*
?開頭,以?*/
?結束,可以跨越多行。 - 用途:注釋較長的代碼塊或暫時禁用代碼。
三、文檔注釋(/?...?/)*
- 語法:以?
/**
?開頭,以?*/
?結束,支持特殊標簽(如?@param
、@return
)。 - 用途:生成 API 文檔(如 JavaDoc),供開發者參考。
強制轉換,自動轉換
類型轉換(Type Casting)?是將一種數據類型轉換為另一種數據類型的過程。根據轉換方式的不同,可分為?自動轉換(隱式轉換)?和?強制轉換(顯式轉換)。
一、自動轉換(隱式轉換)
1. 概念
- 無需顯式聲明,編譯器自動完成。
- 小范圍類型?向?大范圍類型?轉換(安全轉換,不會丟失數據)。
2. 轉換規則
byte → short → int → long → float → double
char → int
3. 示例
// 整型轉浮點型
int num = 10;
double d = num; // 自動轉換:int → double,d = 10.0// 字符轉整型
char c = 'A';
int ascii = c; // 自動轉換:char → int,ascii = 65// 多種類型混合運算
byte b = 5;
int i = 10;
float f = 3.14f;
double result = b + i + f; // 結果為 double 類型
二、強制轉換(顯式轉換)
1. 概念
- 需要顯式使用語法:
(目標類型) 值
。 - 大范圍類型?向?小范圍類型?轉換(可能丟失數據,需謹慎)。
2. 轉換規則
double → float → long → int → short → byte
int → char
3. 示例
// 浮點型轉整型(截斷小數部分)
double d = 3.99;
int i = (int) d; // 強制轉換:double → int,i = 3(小數部分丟失)// 大范圍整型轉小范圍整型(可能溢出)
long l = 1000L;
short s = (short) l; // 強制轉換:long → short,s = 1000(在 short 范圍內)long big = 3000000000L;
int small = (int) big; // 溢出:small = -1294967296(數據錯誤)// 整型轉字符(根據 ASCII 碼轉換)
int code = 65;
char c = (char) code; // 強制轉換:int → char,c = 'A'
?邏輯運算符
一、基本邏輯運算符
&(且)運算符:運算符兩邊只要有 false 則結果為 false,
|(或)運算符:運算符兩邊只要有 true 則結果為 true,
^(異或)運算符:運算符兩邊同為 false 或 true 則結果為 false,如果不相同則結果為 true,
!(非)運算符:就是邏輯非,取反,如:運算符后是 false,則結果為 true。
& 與 &&、| 與 || 的最終結果是一樣的,但是他們之間還是有區別的:
&& 運算符:具有短路效果,如果運算符左邊為 false,右邊將不再執行直接給出結果為 false。
而 & 運算符:即使運算符左邊已經為 false,還是會執行運算符右邊,最后再結合起來判斷得出最后結果為 false。
| 運算符與 || 運算符類似。
二、位運算符
位運算符有:&、|、^、~、<<、>>、<<<、>>>
注意:如果 &、|、^ 這三個運算符兩邊是數值則為位運算符,如果兩邊是 boolean 類型值則作為邏輯運算符。
位運算符:進行的操作都是二進制的,也就是說在操作之前需要先把數據轉換為二進制數。
?多態:
這里我一直沒明白的點是,類似Shape circle = new Circle()的代碼的為什么這么寫?對比:Circle circle = new Circle();好在了哪里?為什么circle不能調用Circle特有的方法?向上轉型意義所在。編譯時是shape,但運行時對象的實際類型是 Circle。這句話什么意思?最后對應的內存圖怎么畫。堆里有沒有父類shape?
Shape circle = new Circle()
面向對象編程中的多態性
在面向對象編程中,多態性允許使用父類或接口類型的引用來指向子類對象。這種設計方式使得代碼更加靈活和可擴展。例如,Shape circle = new Circle()
中,Shape
是父類或接口,Circle
是子類。通過這種方式,可以在不改變代碼結構的情況下,替換不同的子類對象。
提高代碼的可維護性
使用父類或接口類型的引用可以減少代碼的耦合度。如果直接使用 Circle circle = new Circle()
,代碼會與具體的 Circle
類緊密耦合。而使用 Shape circle = new Circle()
,代碼只依賴于 Shape
接口或父類,未來可以輕松替換為其他實現了 Shape
接口的類,如 Rectangle
或 Triangle
。
實現統一的接口調用
通過父類或接口類型的引用,可以統一調用接口中定義的方法。例如,Shape
接口可能定義了 draw()
方法,Circle
和 Rectangle
都實現了這個方法。使用 Shape circle = new Circle()
后,可以調用 circle.draw()
,而無需關心具體的子類實現
總結
Shape circle = new Circle()
這種寫法充分利用了面向對象編程的多態性,提高了代碼的靈活性和可維護性。通過使用父類或接口類型的引用,可以統一調用接口方法,并且在不改變代碼結構的情況下,輕松替換不同的子類實現。
public class Test {public static void main(String args[]) {int x, y;x = 5 >> 2;y = x >>> 2;System.out.println(y);}
}
代碼執行步驟
-
變量聲明:
int x, y;
聲明兩個整數變量?x
?和?y
。 -
計算?
x = 5 >> 2
- 5 的二進制表示:
0000 0101
(假設為 32 位整數)。 - 右移 2 位(
>> 2
):將所有位向右移動 2 位,高位補符號位(正數補 0)。
結果:0000 0001
?→ 十進制值為?1。 - 因此,
x
?的值為?1。
- 5 的二進制表示:
-
計算?
y = x >>> 2
- x 的值(1)的二進制:
0000 0001
。 - 無符號右移 2 位(
>>> 2
):將所有位向右移動 2 位,高位補 0(無論正負)。
結果:0000 0000
?→ 十進制值為?0。 - 因此,
y
?的值為?0。
- x 的值(1)的二進制:
-
輸出結果:
System.out.println(y);
?打印?0。
-
>>
?與?>>>
?的區別:>>
(帶符號右移):高位補符號位(正數補 0,負數補 1)。>>>
(無符號右移):高位始終補 0,適用于處理無符號數或需要邏輯右移的場景。
為什么有包裝類
一、滿足面向對象編程的需求
-
基本類型不是對象:
Java 是面向對象語言,但?int
、double
?等基本類型不具備對象的特性(如方法調用、繼承)。包裝類將基本類型轉換為對象,使其可參與面向對象的操作。 -
泛型的限制:
泛型(如?List<T>
、Map<K,V>
)只能使用對象類型,無法直接存儲基本類型。包裝類解決了這一問題:List<Integer> list = new ArrayList<>(); // 合法 // List<int> list = new ArrayList<>(); // 非法
二、支持序列化與反射
-
序列化(Serialization):
對象可通過序列化在網絡傳輸或保存到文件,而基本類型不支持。包裝類使基本數據具備序列化能力:Integer num = 10; // 可序列化 ObjectOutputStream oos = new ObjectOutputStream(...); oos.writeObject(num); // 合法
-
反射(Reflection):
反射機制只能操作對象,包裝類允許基本類型參與反射:Class<?> clazz = Integer.class; Method method = clazz.getMethod("toString");
三、提供實用方法
包裝類提供了許多靜態方法和常量,增強基本類型的功能:
// 字符串轉基本類型
int num = Integer.parseInt("123");// 進制轉換
String binary = Integer.toBinaryString(255); // "11111111"// 最大值/最小值常量
long max = Long.MAX_VALUE; // 9223372036854775807// 自動裝箱/拆箱
Integer obj = 10; // 自動裝箱:int → Integer
int primitive = obj; // 自動拆箱:Integer → int
四、自動裝箱與拆箱(Autoboxing/Unboxing)
Java 5 引入的特性,允許基本類型與包裝類自動轉換,簡化代碼:
// 自動裝箱
Integer a = 10; // 等價于 Integer a = Integer.valueOf(10);// 自動拆箱
int b = a; // 等價于 int b = a.intValue();// 集合操作
List<Integer> list = new ArrayList<>();
list.add(1); // 自動裝箱:int → Integer
int first = list.get(0); // 自動拆箱:Integer → int
?final和finally的區別??
一、final(修飾符)
1. 作用
- 修飾類:類不可被繼承(如?
String
、Math
)。 - 修飾方法:方法不可被重寫。
- 修飾變量:變量成為常量,只能賦值一次。
2. 示例
// 1. 修飾類
final class ImmutableClass { }
// class SubClass extends ImmutableClass {} // 編譯錯誤:無法繼承 final 類// 2. 修飾方法
class Parent {public final void print() { }
}
// class Child extends Parent {
// @Override
// public void print() {} // 編譯錯誤:無法重寫 final 方法
// }// 3. 修飾變量
final int MAX_SIZE = 100;
// MAX_SIZE = 200; // 編譯錯誤:無法修改 final 變量
二、finally(異常處理)
1. 作用
在?try-catch
?結構中,finally
?塊中的代碼?無論是否發生異常都會執行,常用于資源釋放(如關閉文件、網絡連接等)。
2. 示例
try {FileInputStream file = new FileInputStream("test.txt");// 讀取文件...
} catch (FileNotFoundException e) {e.printStackTrace();
} finally {// 無論是否發生異常,finally 塊都會執行System.out.println("Finally block executed");
?