影片連結
一、基礎入門
1.1 JRE和JDK
-
JDK是什麼?由哪些內容組成
JDK是Java開發工具包
- JVM虛擬機器:Java程式執行的地方
- 核心類庫:Java已經寫好的東西,我們可以直接用
- 開發工具:javac、java、九點半、jhat等
-
JRE是什麼?由哪些內容組成?
JRE是Java執行環境
JVM、核心類庫、執行工具
-
JDK、JRE、JVM三者的包含關係
JDK包含了JRE
JRE包涵了JVM
二、Java的基礎語法
2.1 註釋
註釋內容不會參與編譯和執行,僅僅是對程式碼的解釋說明
2.1.1 單行註釋
// 註釋資訊
2.1.2 多行註釋
/* 註釋資訊 */
2.1.3 文件註釋
/** 註釋資訊*/
2.2 關鍵字
2.2.1 什麼是關鍵字
被Java賦予了特殊含義的英文單詞
2.2.2 關鍵字的特點
- 關鍵字的字母全部小寫
2.2.3 Class關鍵字的含義
用於建立/定義一個類,類是JAVA最基本的組成單元,後面跟隨類名
2.3 字面量
資料在程式中國呢的書寫格式
2.3.1 字面量型別
字面量型別 | 說明 | 舉例 |
---|---|---|
整數型別 | 不帶小數點的數字 | 123 |
小數型別 | 帶小數點的數字 | 1.3,44.3 |
字串型別 | 用雙引號括起來的內容 | "HelloWorld","我對自己" |
字元型別 | 用單引號括起來的,內容只能有一個 | 'A','B' |
布林型別 | 只有兩個值 | true,false |
空型別 | 特殊的值:null | null |
2.3.2 特殊符號
-
\t
製表符在列印的時候,把前面字串的長度補齊到8,或者8的整數倍。至少補一個空格,最多補8個空格。
-
\n
2.4 變數
2.4.1 變數的定義格式
資料型別 變數名 = 資料值;
2.4.2 變數的注意事項
- 只能儲存一個值
- 變數名不允許重複定義
- 一條語句可以定義多個變數
- 變數在使用之前一定要進行賦值
- 變數的作用域範圍
三、 計算機的儲存規則
計算機中,任意資料都是一二進位制的形式來儲存的
- 二進位制:由0和1組成,程式碼中以
0b
開頭 - 十進位制:由0~10組成
- 八進位制:由0~7組成,程式碼中以
0
開頭 - 十六進位制:由0~F組成,程式碼中以
0x
開頭
任意進位制轉十進位制
公式:係數*基數的權次冪. 相加
- 係數:每一位上的數
- 基數:當前進位制數
- 權:從右向左,一次為0,1,2,3,4,5…
十進位制轉其他進位制
除基取餘法
- 不斷的除以基數,得到餘數,直到商為0,再將魚屬倒著拼起來即可
3.1 Text文字
3.1.1 數字
轉二進位制儲存
3.1.2 字母
對應的ASCII表的值轉二進位制
3.1.3 漢字
對應的uniCode碼錶轉二進位制
3.2 Image圖片
透過每一個畫素點鐘的RGB來儲存
3.3 Sound聲音
對聲音的波形圖進行取樣再儲存
四、 JAVA的基本語法
4.1 資料型別
4.1.1 基本資料型別
資料型別 | 關鍵字 | 取值範圍 |
---|---|---|
數字 | byte | -128~127 |
short | -32768~32767 | |
int | -214743648~2147483647 | |
long | -9223372036854775808~9223372036854775807 | |
浮點數 | float | -3.401298e-38~3.402823e+38 |
double | -4.9000000e-324~1.797693e+308 | |
字元 | char | 0~65535 |
布林 | boolean | true,false |
long型別在資料後面要新增字母
L
,雖然大小寫不限,但建議使用大寫long l = 999999999L;
float型別要再資料後新增
F
,同上float f = 9999.3F;
數字型別的取值範圍的排列:
double
>float
>long
>int
>short
>byte
4.1.2 引用資料型別
暫時空
4.2 標誌符
就是給類、變數、方法起的名字
-
由數字、字母、下劃線和美元符組成
-
不能以數字開頭
-
不能是關鍵字
-
區分大小寫
4.2.1 小駝峰命名法
用於給方法、變數命名
- 首單詞首字母小寫,後面的單詞首字母大寫
- 只有一個單詞時,全部小寫
4.2.2大駝峰命名
用於類名命名
- 所有單詞首字母大寫
4.3 鍵盤錄入
步驟:
-
導包:匯出
Scanner
這個包import java.util.Scanner; // 導包的動作必須在類定義的上面
-
建立物件:準備使用
Scanner
這個包Scanner sr = new Scanner(System.in); // sr是變數名,可變,其他的不允許
-
接受資料:真正使用這個
Scanner
int number1 = sr.nextInt(); // 只有i是變數名,別的不允許變
eg:
import java.util.Scanner;
public class PrintSomeSthing {
public static void main(String[] args){
Scanner sr = new Scanner(System.in);
System.out.println("請輸入第一個數字");
int number1 = sr.nextInt();
System.out.println("請輸入第二個數字");
int number2 = sr.nextInt();
System.out.println("兩個數的和為:"+(number1+number2));
}
}
五、運算子
-
運算子和表示式
運算子:對字面量或者變數進行操作的符號
表示式:用運算子將變數或者字面量連線起來,符合Java運算的式子稱為表示式
int a = 10; int b = 15; System.out.println(a+b)
+
就是運算子a + b
就是表示式- 由於
+
是算數運算子,所以a + b
叫做算數表示式
5.1 算數運算子
-
加
+
-
減
-
-
乘
*
-
除
/
-
取模/取餘
%
-
但是算數運算子在計算浮點數的時候並不是完全準確,如下:
System.out.println(1.1 + 1.01); //2.1100000000000003 System.out.println(1.1 - 1.01); //0.09000000000000008 System.out.println(1.1 * 1.01); //1.1110000000000002 System.out.println(0.1+0.2); //0.30000000000000004
這種情況是因為算數過程基於
IEEE754
運算,導致的誤差。原文
-
練習:
/**
* 剝離number的個、十、百位的數字
* */
public class demo1 {
public static void main(String[] args) {
int number = 321;
int g = number % 10;
int s = number /10%10;
int b = number / 100%10;
System.out.println(g);
System.out.println( s);
System.out.println(b);
}
}
5.1.2 隱式轉換
當資料型別不同時,是不能直接進行計算的
-
把一個取值範圍小的數值型別,轉換成取值範圍大的資料型別後再進行計算
/** * 算數運算子的隱形轉換 */ public class demo2 { public static void main(String[] args) { int number1 = 12; double double1 = 22.0; System.out.println(number1+double1); //34.0 } }
-
byte
,short
,char
三種資料型別會先提升為int
再進行計算/** * 算數運算子的隱形轉換 */ public class demo2 { public static void main(String[] args) { short short1 = 23; byte byte1 = 10; System.out.println(short1+byte1); //43 } }
5.1.3 強制轉換
如果我們想把一個取值範圍較大的變數,複製給取值範圍較小的變數,那麼我們就需要強制轉換
-
格式:
目標資料型別 變數名 = (目標資料型別) 被強轉的資料
/** * 資料強轉 * */ public class demo3 { public static void main(String[] args) { int number1 = 123; short cha1 = (short) number1; System.out.println(cha1); } }
使用計算運算子+
轉化資料型別為字串
數值相加
- 略,與正常計算無異
字串相加
- 當
+
操作出現字串時,這個+
是字串連續符,而不是算數運算子,會講前後的資料進行拼接,產生一個新的字串 - 連續進行
+
操作時,從左到右逐個執行
字元相加
-
byte
,short
,char
這三種型別的資料在運算時,會提升為int
再進行計算當與一個
char
型別進行操作的時候,會將這個char
轉換成相應的ASCII
值,再進行操作/** * 加號不同操作運算 */ public class demo4 { public static void main(String[] args) { //1.數值與數值相加 int num1 = 12; float f1 = 12.3F; System.out.println(num1 + f1); //24.3 // 2. 與字串相操作 System.out.println(1+"123"); //1123 // 連續操作的時候,從左到右逐次操作 System.out.println(1+3+"333"); //4333 //3. 與字元相操作 System.out.println(1+'a'); //98 System.out.println(1+3+"dd"+'a'); //4dda } }
小結
- 字串並沒有
-
,*
,/
,%
的運算的; /
和%
的區別:兩個資料做除法,/
取結果的商,%
取結果的餘數- 整數與整數操作,只能得到整數,想得到小數,必須有浮點數參與運算
5.2 自增自減運算子
符號 | 說明 |
---|---|
++ |
自加 |
-- |
自減 |
- 前置
++
,--
,先操作後使用- 後置
++
,--
,先使用後操作
5.3 賦值運算子
符號 | 作用 | 說明 |
---|---|---|
= |
將右面的值賦值給做面 | int a = 10 |
+= |
加後賦值 | a+=b |
-= |
~ | ~ |
*= |
~ | ~ |
/= |
~ | ~ |
%= |
取餘後賦值 | ~ |
以上,除了等號(
=
)其他的擴充套件運算子,都包含了強制轉換。/** * 擴充套件賦值運算子的強制型別轉換 * */ public class demo5 { public static void main(String[] args) { int d1 = 123; d1 += 1.1; System.out.println(d1); // 124 } }
會將被操作值的資料型別(在案例裡的
1.1
)強制轉化為目標資料型別(案例裡d1
),即將1.1
轉化為int
後再進行相加賦值給d1
.
Java
中將浮點數轉化為int
時,會直接去掉小數點後的數值。
5.4 關係運算子
符號 | 說明 |
---|---|
== |
a==b 判斷a 和b 是否相等,成立為true ,不成立為false |
!= |
a!=b 判斷a 與b 不想等,成立返回true ,不成立返回false |
> |
判斷大於~ |
>= |
判斷大於等於~ |
< |
判斷小於~ |
<= |
判斷小於等於~ |
5.5 邏輯運算子
-
普通邏輯運演算法
符號 作用 說明 &
邏輯與(且) 兩遍均為 true
,結果才是true
` ` 邏輯或 ^
邏輯異或 相同為 false
,不同為true
!
邏輯非 取反 -
短路邏輯運算子
符號 作用 說明 &&
短路與 結果與 &
相同,但是有短路效果` ` Eg:
a&&b
,若a
表示式的結果為false
那麼b
表示式不會執行,否則兩邊都執行a||b
,若a
表示式的結果為true
那麼b
表示式不會執行,否則兩邊都執行
5.6 三元運算子
-
三元運算子為
?
格式為:
關係表示式 ?表示式1 : 表示式2
計算規則:
- 先計算關係表示式
- 關係表示式的結果為
true
,結果為表示式1的結果,否則為表示式2的結果
5.7運算子優先順序
優先順序 | 運算子 |
---|---|
1 | . ,() ,{} |
2 | ! ,~(安位取反) ,++ ,-- |
3 | * ,/ ,% |
4 | + ,- |
5 | << ,>> ,>>> (位運算) |
6 | < ,<= ,> ,>= ,instanceof |
7 | == ,!= |
8 | & |
9 | ^ |
10 | ` |
11 | && |
12 | ` |
13 | ?:(三目) |
14 | = ,+= ,-= ,= ,/= ,%= ,&= … |
六、流程控制語句
6.1 順序結構
預設就是順序結構
6.2 分支結構
6.2.1 if
-
寫法一
if(關係表示式){ //程式碼段 }
-
寫法二
if() //只有一行的程式碼
要注意,定義變數,無論是否顯性賦值,都算兩句程式碼(1.定義變數的語句;2. 給變數賦值的語句)
- Java語言中規定當
if
語句不佳大括號時,不可以發表宣告,因為作用域就一條語句,而現在這個語句卻用來宣告變數或建立一個物件,這個區域性斌量和物件是沒有意義的(因為,剛建立,宣告週期就結束了),因此禁止這樣使用。
- Java語言中規定當
-
寫法三
if(){ }else{ } //========================== if (){ }else if(){ }else{ }
6.2.2 switch
-
傳統寫法
略,與其他語言相同
-
jdk12
以上版本新特性public class demo7 { public static void main(String[] args) { int num = 2; switch (num) { case 1 -> { System.out.println("這是1"); } case 2 -> System.out.println("這是2"); case 3 -> System.out.println("這是3"); default -> System.out.println("這是default"); } } }
- 可以用
case ***->{}
的方式來不寫break
,如果只有一行程式碼{}
可以省略。
- 可以用
6.3 迴圈結構
for
while
使用時的選擇:
for
迴圈中:知道迴圈次數,或者迴圈範圍while
迴圈中,不知道迴圈次數和範圍,只知道迴圈的結束條件
-
do...while
do{ }while(條件表示式)
6.4 跳轉控制語句
continue
跳過本次迴圈,繼續下一次迴圈break
,結束迴圈
七、 陣列
7.1 陣列介紹
陣列指的是一種容器,可以用來儲存同種資料型別的多個值;
- 容器在儲存資料的時候,需要結合隱式轉換考慮。
- 如:
int
型別的陣列容器(byte
,short
,int
是可以存入到這個int
型別的陣列中的,但是boolean
,double
並不能存入) - 如:
doubule
型別的陣列容器(byte
,short
,int
,long
,float
,double
)都可以存入到double
的陣列中
- 如:
7.2 陣列的定義與靜態初始化
7.2.1 陣列的定義
-
格式一
資料型別 [] 陣列名
int [] array1
-
格式二
資料型別 陣列名[]
int array2[]
7.2.2 陣列的初始化(靜態初始化)
-
靜態初始化
格式:
資料型別 []陣列名 = new 資料型別[]{元素1,元素2,元素3,元素4,...};
int [] array1 = new int[]{1,2,3,8,5,6,0,7};
可簡化為:
資料型別 []陣列名 = {元素1,元素2,元素3,元素4,...};
int [] array1 = {1,2,3,8,5,6,0,7};
public class test1 { public static void main(String[] args) { double [] array1 = {1,2,3,8,55,5,6,0,7}; System.out.println(array1); //[I@372f7a8d } }
直接列印陣列,不會直接列印陣列的值,而是列印陣列的地址
[
代表是個陣列I
代表是int
型別(D
代表double
等等)@
是固定格式372f7a8d
是資料的地址
-
動態初始化
格式:
資料型別 [] 變數名 = new 資料型別[陣列長度]
//定義了一個長度為5的陣列 int [] arr = new int[5]
7.2.3 動態初始化與靜態初始化的區別
- 動態初始化:手動指定陣列長度,由系統給出預設初始化值。
- 只明確各書,不明確具體數值
- 靜態初始化:手動指定陣列元素,系統會根據元素個數,計算長度
- 已知道具體的資料
7.3 陣列元素訪問
格式:陣列名[索引]
。
索引從
0
開始,逐個+1
。
public class test1 {
public static void main(String[] args) {
double [] array1 = {1,2,3,8,55,5,6,0,7};
System.out.println(array1); //[I@372f7a8d
System.out.println(array1[5]); // 5.0
// 給陣列第一個值修改為100
array1[0] = 100;
System.out.println(array1[0]); // 100.0
}
}
7.4 陣列遍歷
public class test2 {
public static void main(String[] args) {
int[] arr = new int[]{1, 3, 4, 5, 6, 7, 23, 7, 8, 9, 0};
for (int i = 0; i < arr.length - 1; i++)
System.out.println(arr[i]);
//1
//3
//4
//5
//6
//7
//23
//7
//8
//9
}
7.5 陣列動態記憶體圖
Java
記憶體分配:
- 棧:方法執行時使用的記憶體,比如
main
方法執行,進入方法棧中執行 - 堆:儲存物件或者陣列,new來建立的都儲存在堆記憶體
- 方法區:儲存可以執行的
class
檔案 - 本地方法棧:JVM在使用作業系統功能的時候使用,與開發無關
- 暫存器:給CPU使用過,與開發無關
JDK8開始,取消方法區,新增元空間,把原來方法區的多種功能進行拆分,有的功能放到了堆中,有的功能做到了元空間中。
八、 方法
8.1 什麼是方法
方法是程式中最小的執行單元
方法的作用:
- 提高程式碼的複用性
- 提高程式碼可維護性
8.2 方法的格式
-
簡單的方法定義
public static void 函式名() { // 函式體 }
e g:
public class function1 { public static void main(String[] args) { printName(); } public static void printName() { // 函式體 System.out.println("hhhhh"); } }
-
帶引數的方法定義
-
public class function1 { public static void main(String[] args) { printName(90,10); } //定義的函式 public static void printName(int num,int age ) { // 函式體 System.out.println("hhhhh"+num+age); } }
-
帶返回值的方法定義
-
public class function1 { public static void main(String[] args) { //呼叫 System.out.println(sum(12, 54)); //66 //呼叫 int res = sum(12,54); System.out.println(res); // 66 } // 定義一個函式 public static int sum(int a, int b) { int res = a + b; return res; } }
方法的注意事項:
- 方法不呼叫就不會執行
- 方法與方法之間是平級關係,不能巢狀定義
- 書寫順序與執行書序無關
- 如果你的函式是
viod
返回值,那麼你可以不寫return
,如果寫return
,那麼return
後面不能返回任何值
8.3 方法的過載
-
在同一個類中,定義了多個同名的方法,和諧同名的方法具有同種的功能。
-
每個方法具有不同的引數型別或個數,這些同名的方法,就構成了過載
同一個類中,方法名相同,引數不同(引數型別不同,個數不同,順序不同,滿足其一即可)的方法就叫過載與返回值無關
/* * 需求: 使用方法過載的思想設計比較兩個整數是否相等的方法 * 要求: 相容全部整數型別(byte,short,int,long) * */ public class overLoad { public static void main(String[] args) { System.out.println( contrast(2099123,2099123)); } public static boolean contrast(byte a, byte b) { return a == b; } public static boolean contrast(short a, short b) { return a == b; } public static boolean contrast(int a, int b) { return a == b; } public static boolean contrast(long a, long b) { return a == b; } }
8.4 方法的記憶體
九、物件導向
9.1 設計物件並使用
類和物件:
-
類:是物件共同特徵的描述
-
物件:是真實存在的具體東西
java中必須先設計類才能獲取物件
9.1.1 定義類
pubilc class 類名 {
1. 成員變數
2.成員方法
3.構造器
4.程式碼塊
5.內部類
}
Javabean類:用來描述一類事物的類,在javabean類中,是不寫main方法的
類名首字母建議大些,需要見名知意,大駝峰命名。
一個Java檔案中可以定義多個class類,且只能有一個使用
public
修飾的類,且使用pubilc
修飾的類名必須與程式碼檔名相同實際開發還是建議一個檔案只定義一個class類
成員變數的完整定義格式是:修飾符 資料型別 變數名稱 = 初始化值,一般無需制定初始化值,存在預設值
測試類:需要寫main方法,的類,我們可以在測試類中建立javabean類的物件並進行賦值,呼叫等操作
物件中不同資料型別的預設值
資料型別 | 明細 | 預設值 |
---|---|---|
基本型別 | byte,short,int,long | 0 |
float,double | 0.0 | |
boolean | false | |
引用型別 | 類,介面,陣列,String | null |
javaBean類:
public class Phone {
//屬性
String brand;
double price;
//方法(行為)
public void call() {
System.out.println("打電話");
}
public void playGame() {
System.out.println("打遊戲");
}
}
測試類:
public class PhoneTest {
public static void main(String[] args) {
//建立物件
Phone p1 = new Phone();
p1.brand = "摩托羅拉";
p1.price = 2344.21;
System.out.println(p1.brand);
System.out.println(p1.price);
p1.call();
p1.playGame();
// 摩托羅拉
// 2344.21
// 打電話
// 打遊戲
}
}
9.2 封裝
物件導向三大特徵:
-
封裝
物件代表什麼,就的封裝對應的資料,並提供資料對應的行為
-
繼承
-
多型
修飾符
-
private
- 是一個許可權修飾符
- 可以修飾成員變數和成員方法
- 被
private
修飾的成員只能在本類中才能訪問
為了能在其他類中能使用
private
修飾的成員,我們會在這個類中新增兩個pubilc
修飾的方法Set和get分別來對成員賦值和取值 -
public
- 同上一、二條
- 被
public
修飾的成員代表公共的,在所有的類中都能訪問
//使用private修飾成員的Javabean類
public class gjz {
private int num;
//set方法
public void setNum(int num) {
//可以在設定值時進行些資料校驗
if (num <= 10) {
System.out.println("你的賦值過低請賦值大於10的值");
return;
}
this.num = num;
}
//get
public int getNum() {
return num;
}
}
// gjz的測試類
public class gjzTest {
public static void main(String[] args) {
gjz g1 = new gjz();
g1.setNum(9); //你的賦值過低請賦值大於10的值
g1.setNum(11);
System.out.println(g1.getNum()); //11
}
}
9.3 this關鍵字
所在方法呼叫者的地址值
- 就近原則,如上圖程式碼,列印的值會優先選擇離自己近的區域性變數的
age
9.4 建構函式
構造方法也叫構造器,建構函式
- 作用:在建立物件的時候給成員變數進行初始化的
建構函式的格式:
pubilc class Student{
修飾符 類名 (引數){
方法體
}
}
注意事項
-
方法名與類名必須相同,包括大小寫
-
沒有返回值型別,連void也不需要要寫DD
-
同時沒有返回值
-
如果沒有定義構造方法,系統將會給一個預設的空參構造器
-
構造器是可以過載的:帶參和無參構造器兩者方法名相同,但引數不同,是可以同時存在的,甚至可以多個構造器
建議無論是否使用,都手動將無參構造器和帶全部引數的構造器定義
執行
- 建立物件的時候由虛擬機器呼叫,不能手動呼叫
- 每建立一次物件,就會自動呼叫一次構造器
帶參構造和空參構造
public class Student {
private String name;
private int age;
public Student() {
System.out.println("我是空參構造器觸發");
//空參構造
}
public Student(String name, int age) {
this.name = name;
this.age = age;
//帶參構造
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
呼叫空參構造器:
public class StudentTest {
public static void main(String[] args) {
Student s1 =new Student(); //我是空參構造器觸發
}
}
呼叫帶參構造器:
public class StudentTest {
public static void main(String[] args) {
Student s1 = new Student("hhh", 14); //我是空參構造器觸發
System.out.print(s1.getAge()+" "+ s1.getName()); //14 hhh
}
}
- 無參構造器:初始化物件時,成員變數的資料均採用預設值
- 有參構造器:在初始化的時候,同時可以為物件成員賦值
9.5 標準JavaBean
9.6 物件記憶體圖
-
一個物件的記憶體圖
-
多個物件的記憶體圖
-
兩個變數之鄉同一個物件記憶體圖
-
this的記憶體原理
-
基本資料型別和引用資料型別的區別
-
區域性變數和成員變數的區別
9.7 補充知識:變數成員,區域性變數區別
區別 | 成員變數 | 區域性變數 |
---|---|---|
類中位置不同 | 類中、方法外 | 方法內、方法申明上 |
初始化值不同 | 有預設初始化值 | 沒有、使用前需要初始化 |
記憶體位置不同 | 堆記憶體的當前類中 | 其值或其地址存於棧記憶體的當前方法中 |
生命週期不同 | 隨著物件的建立而存在,隨著物件的消失而消失 | 隨著方法的呼叫而存在,隨著方法的執行結束而消失 |
作用域 | 整個類中有效 | 當前方法中有效 |
十、String
10.1定義字串
-
直接賦值
String str = "1234"
-
new
構造方法 說明 public String() 建立空白字串,不含任何內容 public String(String original) 根據傳入的字串建立字串物件 Public String (char[] chs) 根據字元陣列,建立字串物件 public String(byte[] chs) 根據自截陣列,建立字串物件
public class Str1 {
public static void main(String[] args) {
//直接賦值
String str1 = "234";
//使用new的方式來建立一個字串物件
String str2 = new String();
String str3 = new String("1235");
System.out.println(str3); // "1235"
//傳遞一個字元陣列建立字串
// 應用場景:修改字串內容的時候,我們可以吧字串轉字元陣列,修改後再透過字元陣列轉回字串
char[] arr = {'1', '2', '5', '9'};
String str4 = new String(arr);
System.out.println(str4); //"1259"
//傳遞一個位元組陣列,根據位元組陣列建立新的字串物件
//拿到byte的值後,會根據byte的值區ASCAII表找到對應的字元,然後再建立字串
//應用場景:在網路中傳輸的資料其實都是位元組,可以把位元組進行轉換成字串,需要這個構造方法
byte[] arr1 = {97,98,99};
String str5 = new String(arr1);
System.out.println(str5); //"abc"
}
}
10.2 兩種建立方式的區別
-
直接賦值的方式
在堆中,還有一塊特殊的記憶體(String Table)串池,專門用於儲存字串的值。但只有直接賦值的字串的值,才會儲存到這個串池中,透過new構造出來的字串物件不會
-
透過直接賦值的字串的值,在串池中會進行儲存,賦值時,會去串池中檢索,有沒有相同的值,如果有,那麼將會複用這個值。否則會重新建立一個值。
public class Str2 { public static void main(String[] args) { String str = "1234"; String str1 = "1234"; String str2 = '222' //這兩個字串引用的是串池中同一個變數 } }
-
-
使用new建立的方式
- 使用
new
出來的字串物件,即使是相同的內容,也不會再對中進行復用。 - 每
new
一次,就會在堆中重新開闢一塊空間用來儲存字串物件
- 使用
10.3 字串的比較
-
==
比較- 基本資料型別比較的是具體的值
- 引用資料型別對比的是資料的地址值
public class test { public static void main(String[] args) { //基本資料型別的比較 int num1 = 1; int num2 = 1; System.out.println(num1 == num2); //true //直接賦值的方式的字串 String str1 = "abc"; String str2 = "abc"; System.out.println(str1 == str2); //true // 直接賦值和new出來的相同內容的字串相比較 String str3 = "cde"; char[] arr = {'c', 'd', 'e'}; String str4 = new String(arr); System.out.println(str3 == str4); //false // 兩個new出來的內容相同的字串相比較 char[] arr1 = {'e', 'f', 'g'}; String str5 = new String(arr1); char[] arr2 = {'e', 'f', 'g'}; String str6 = new String(arr2); System.out.println(str5 == str6); //false } }
-
boolean equals(要比較的字串)
使用
equals
方法,不忽略大小寫,內容需要完全一樣,結果才能是truepublic class Str4 { public static void main(String[] args) { String str = new String("1234"); String str1 = "1234"; boolean res = str1.equals(str); System.out.println(res); //true String str2 = new String("abc"); String str3 = "Abc"; System.out.println(str2.equals(str3)); //false } }
-
boolean equalsIgnoreCase(要比較的字串)
使用
equalsIgnoreCase
,忽略大小寫,內容一樣,返回truepublic class Str4 { public static void main(String[] args) { String str = new String("1234"); String str1 = "1234"; boolean res = str1.equalsIgnoreCase(str); System.out.println(res); //true String str2 = new String("abc"); String str3 = "Abc"; System.out.println(str2.equalsIgnoreCase(str3)); //true } }
10.4 StringBuilder
StringBuilder
可以看作是一個容器,建立之後裡面的內容是可變的。
-
構造方法
構造方法 說明 public StringBuilder()
建立一個空的可變字串物件 public StringBuilder(String str)
以 str
為初始值,構造一個可變字串物件在
Java
的底層,對StringBuilder
做了一些特殊處理,我們直接列印StringBuilder
例項物件,列印的是物件的屬性值,而不是地址值。但是本質還是物件。public class Str5 { public static void main(String[] args) { StringBuilder sb = new StringBuilder("abc"); System.out.println(sb); // abc } }
-
常用API
方法名 說明 public StringBuilder append(任意型別資料)
新增資料,並返回物件本身 pubilc StringBuilder reverse()
反轉容器中的內容 public int length()
返回屬性值的長度 public String toString()
將 StringBuilder
物件轉化成字串並返回public class Str5 { public static void main(String[] args) { StringBuilder sb = new StringBuilder("abc"); sb.append("sss"); sb.append("113").append(1234).append(true); System.out.println(sb); //abcsss1131234true sb.reverse(); System.out.println(sb); //eurt4321311ssscba int len = sb.length(); System.out.println(len); //17 String res = sb.toString(); System.out.println(res); //eurt4321311ssscba } }
10.5 StringJoiner
是
JDK8
出的一個可變的操作字串的容器,可以高效,方便的拼接字串
-
構造方法
方法 說明 public SrtringJoiner(間隔符號)
建立一個 StringJoiner
物件,使用制定的間隔符號連線public StringJoiner(間隔符號,開始符號,結束符號)
建立一個 StringJoiner
物件,使用指定的間隔、開始、結束符號連線import java.util.StringJoiner; public class Str6 { public static void main(String[] args) { StringJoiner sj = new StringJoiner("=="); sj.add("123").add("123.1"); System.out.println(sj); //123==123.1 StringJoiner sj1 = new StringJoiner(",","[","]"); sj1.add("1").add("3").add("6"); System.out.println(sj1); //[1,3,6] } }
-
常用API
方法 說明 public StringJoiner add(新增的內容)
新增內容 public int length
返回字串物件屬性值的長度 public String toString()
將拼接後的結果轉換成字串物件,並返回
10.6 字串拼接的底層原理
分為兩種程式碼情況:
-
沒有變數參與
public class Str7 { public static void main(String[] args) { String s = "a"+"b"+"c"; System.out.println(s); //abc String s1 = "abc"; System.out.println(s1 == s); //true } }
上面的程式碼,在編譯階段,
java
會判斷,字串s
的生成沒有其他變數的引數,直接在編譯階段就直接將拼接操作完成。 -
有其他變數的引數
public class Str7 { public static void main(String[] args) { String s = "a"; String s1 = s+"b"; String s2 = s1 + "c"; System.out.println(s2); //abc } }
在JDK8前,Java底層會使用
StringBuilder
進行操作,
十一、 集合
-
陣列和集合的差別
-
長度:
- 組合的長度是固定的,
- 集合的長度不固定,插入一條資料,資料長度就自動加一,刪除一條資料就,資料長度就自動減一
-
儲存資料型別
- 陣列可以存基本資料型別也可以存引用資料型別
- 集合只能儲存引用資料型別,儲存基礎資料型別需要使用基礎資料型別對應的包裝類
-
11.1 ArrayList
11.1.1建立ArrayList
import java.util.ArrayList;
ArrayList<E> 名稱 = new ArrayList<E>()
範型:限定集合中儲存資料的型別
-
在
JDK7
前:ArrayList<String> list = new ArrayList<String>();
-
在
JDK7
後,可以省略後面的範型ArrayList<String> list = new ArrayList<>();
(附加)11.1.1 包裝類
基本資料型別對應的包裝類
基本型別 | 對應包裝類 |
---|---|
byte | Byte |
short | Short |
char | Character |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
11.1.2 ArrayList
的成員方法
操作 | 方法名 | 說明 |
---|---|---|
增 | boolean add(E e) | 新增元素,返回值表示是否新增成功 |
刪 | Boolean remove(E e) | 刪除指定元素,返回值表示是否刪除成功 |
刪 | E remove(int index) | 刪除指定元素索引的元素,返回被刪除元素 |
改 | E set(int index,E e) | 修改制定索引下的元素,返回原來的元素 |
查 | E get(int index) | 獲取制定索引的元素 |
查 | int size() | 集合的長度,也就是集合中元素的個數 |
import java.util.ArrayList;
public class list1 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
System.out.println(list.add("addSth")); // true
System.out.println(list.add("aaacc")); // true
System.out.println(list.add("aaacc")); // true
System.out.println(list); //[addSth, aaacc, aaacc]
// remove只會操作第一個匹配到的元素,操作成功返回true,操作失敗返回false,未匹配到也會返回false
System.out.println(list.remove("aaacc")); // true
System.out.println(list); // [addSth, aaacc]
// 透過index使用remove進行刪除
System.out.println(list.remove(0)); // "addSth"
System.out.println(list); // [aaacc]
// set會返回被替換的值
System.out.println(list.set(0, "newSth")); //aaacc
System.out.println(list); // [newSth]
// get獲取當前索引的元素
System.out.println(list.get(0)); //newSth
//與Array不通,ArrayList的長度需要藉助size()來獲取
System.out.println(list.size()); // 1
}
}
11.1.3 ArrayList
練習
練習1
需求:定義一個集合,新增數字,並進行遍歷
遍歷格式參照:[元素1,元素2,元素3]
public class list2 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.print("[");
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
System.out.print(list.get(i));
} else {
System.out.print(list.get(i) + ",");
}
}
System.out.println("]");
}
}
// [1,2,3,4]
練習2
需求:定義一個集合,新增一些學生物件,並進行遍歷
學生類的屬性為:姓名,年齡
import java.util.ArrayList;
public class list3 {
public static void main(String[] args) {
// 建立集合
ArrayList<Student> list = new ArrayList<>();
//建立學生物件
Student s1 = new Student(12, "zhang");
Student s2 = new Student(44, "chen");
Student s3 = new Student(21, "wang");
//新增元素
list.add(s1);
list.add(s2);
list.add(s3);
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
System.out.println(stu.getName()+","+stu.getAge());
}
}
}
//zhang,12
//chen,44
//wang,21
練習3
- 需求: main方法中定義一個集合,存入三個使用者物件,使用者屬性為:id,username,password
- 要求:定義一個方法,根據id查詢對應的使用者資訊,如果存在返回索引,否則-1
/*
* 需求: main方法中定義一個集合,存入三個使用者物件,使用者屬性為:id,username,password
* 要求:定義一個方法,根據id查詢對應的使用者資訊,如果存在返回索引,否則-1
* */
package com.study.List;
import java.util.ArrayList;
public class list4 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList<>();
User u1 = new User("1345", "hong", "12356");
User u2 = new User("1346", "zhi", "123554");
User u3 = new User("1347", "guo", "12352");
list.add(u1);
list.add(u2);
list.add(u3);
System.out.println(contains(list, "1345")); // true
}
public static int contains(ArrayList<User> list, String id) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getId().equals(id)) {
return i;
}
}
return -1;
}
}
11.1.4注意事項
-
集合中不能直接儲存基本資料型別(
byte
,short
,int
,double
,long
,boolean
,float
,char
),需要使用它們對應的包裝類進行儲存 -
我們建立的是
ArrayList
的物件,而ArrayList
是Java
已經寫好的一個類,在底層做了特殊處理,列印時候不會是地址值,而是集合中儲存的資料內容,在展示的時候會拿[]
把所有的資料進行包裹public class list1 { public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); System.out.println(list); // [] } }
System.exit(int status)這個方法是用來結束當前正在執行中的java虛擬機器。
status是非零引數,那麼表示是非正常退出。
System.exit(0)是正常退出程式,而System.exit(1)或者說非0表示非正常退出程式。
在一個if-else判斷中,如果我們程式是按照我們預想的執行,到最後我們需要停止程式,那麼我們使用System.exit(0),而System.exit(1)一般放在catch塊中,當捕獲到異常,需要停止程式,我們使用System.exit(1)。這個status=1是用來表示這個程式是非正常退出。
十二、物件導向
12.1 static
Static表示靜態,是java中的一個修飾符,可以修飾成員方法、成員變數
- 被static修飾的成員變數,叫靜態變數
- 被static修飾的成員方法,叫靜態方法
12.1.1 靜態變數
-
特點:
-
使用static修飾的成員變數、方法,被該類所有物件共享
-
不屬於物件,屬於類
-
隨著類載入而載入,優先於物件存在
package d01.staticDemo1; public class Student { // 姓名,年齡,性別 // 私有變數,只能類內部能進行訪問,所以外部訪問私有變數,需要在類裡建立對應的get和set函式,在類內部訪問 private String name; private int age; private String gender; // 公共變數,可以在所有類的例項物件中使用,如: Student s1 = new Student(); s1.t="hhh"; public String t; // 靜態變數,不需要書寫get set函式,整個類可以共用這個變數的值, - 外部可以直接透過類.變數名的方式進行呼叫操作如:Student.tAge = 12 static Integer tAge; public Student() { } public Student(int age, String name) { this.age = age; this.name = name; } public Student(String name, int age, String gender) { this.name = name; this.age = age; this.gender = gender; } // 行為 public void study(){ System.out.println(name+"學習"); } public void showInfo(){ System.out.println(name +" "+ age +" "+ gender+"t的資料:"+t); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
// 呼叫 package d01.staticDemo1; public class StudentTest { public static void main(String[] args) { // 直接呼叫class中的靜態變數 Student.tAge = 34; // 使用無參構造器生成一個物件 Student s1 = new Student(); // 類的物件可以直接對public變數進行直接賦值修改 s1.t = "hhh"; // 對私有變數需要使用class中定義的get和set函式進行取值和賦值 s1.setName("小洪"); s1.setAge(18); s1.setGender("男"); System.out.print(s1.getName() + "++++ "); s1.showInfo(); Student s2 = new Student(18, "zzz"); /* * tAge,是靜態變數,在上面賦值過後嗎,資料會存在常量池內,所以在其他的物件中呼叫tAge也是會存在上面賦值的資料的 * t 是公共變數,與s1相同,不需要使用get函式,也可以訪問,不需要使用set函式也可以操作 * s2使用的是Student的有參構造器,並根據過載,選擇兩個引數且型別匹配的構造器,內部對age與name進行賦值 * */ System.out.println(s2.getAge()+" "+s2.getName()+" "+ Student.tAge+" "+s2.t); s2.setGender("女"); System.out.println(s2.t); } }
static
是跟隨class的建立而建立的,優於new的物件建立,所以在所有的物件中都能訪問到static修飾的變數、方法
-
-
呼叫方式:
-
類名呼叫(推薦)
-
物件名呼叫
// StaticDemo package d01.staticDemo1; public class StaticDemo { public String c_name; // 這個static也是idea生成的?狗屎,肯定是我自己定義的啊那不結了 還不是你卸的doge static Integer c_age; public String getC_name() { return c_name; } public void setC_name(String c_name) { this.c_name = c_name; } }
//呼叫 package d01.staticDemo1; public class StaticDemoTest { public static void main(String[] args) { // static修飾的變數、方法的吊用方式透過class呼叫 // 推薦使用class的方式進行呼叫 StaticDemo.c_age = 18; StaticDemo st1 = new StaticDemo(); System.out.println(StaticDemo.c_age ); st1.c_age = 20; System.out.println(StaticDemo.c_age + "+++"+ st1.c_age); } }
-
總結:
- 靜態方法只能訪問靜態變數和靜態方法
- 非靜態方法可以訪問靜態變數和靜態方法,也可以訪問非靜態變數和非靜態方法
- 靜態方法中沒有this關鍵字
12.1.2 靜態方法
-
特點:
- 多用於測試類和工具類中
- Javabean類中很少使用
-
呼叫方式:
-
類名呼叫(推薦)
-
物件名呼叫
可以呼叫本類的靜態方法,也可以呼叫其他類的靜態方法,用類名或者其他類的物件名都可以進項呼叫
-
12.2 繼承
12.2.1 什麼是繼承?繼承有哪些好處?
- 繼承是物件導向三大特徵之一,可以讓類跟類之間產生子父的關係
- 可以把多個子類中重複的程式碼抽取到父類中,子類可以直接使用,減少程式碼冗餘,提高程式碼複用性
-
java中提供了一個
extends
關鍵字,可以讓一個類和另一個建立起繼承關係public class Student extends Person
-
Student 稱為子類(派生類),Person稱為父類(基類或超類)
使用繼承的好處是:
- 可以把多個子類中重複的程式碼抽取到父類中,提高程式碼的複用性
- 子類可以在父類的基礎上,增加其他的功能,使子類更強大
- 不能盲目的抽取父類,必須要子類的意義相同,有共同特性,且存在共同成員變數才可以
12.2.2 繼承的特點
- 子類可以得到父類的屬性和行為,子類可以使用
- 子類可以在父類的基礎上進行新增其他功能, 子類變得更加強大
- java中只支援單繼承,不支援多繼承,但支援多層繼承
- 單繼承:一個子類只能繼承一個父類
- 多層繼承:子類A可以繼承父類B,父類B還可以繼承父類C,以此類推(則C是A的間接父類,B是A的直接父類)
- 每一個類都直接或間接的繼承與Object
- 子類只能訪問父類中非私有的成員
練習:
四種動物分別有以下行為:
- 布偶貓:吃飯、喝水、抓老鼠
- 狸花貓:吃飯、喝水、抓老鼠
- 哈士奇:吃飯、喝水、看家、拆家
- 泰迪:吃飯、喝水、看家、蹭一蹭
// 動物類
package d01.extendsStudy;
public class Animal {
public void eat() {
System.out.println("吃飯");
}
public void drink() {
System.out.println("喝水");
}
}
// 貓類
package d01.extendsStudy;
public class Cat extends Animal {
public void catchMouse (){
System.out.println("抓老鼠");
}
}
// 狗類
package d01.extendsStudy;
public class Dog extends Animal {
public void lookHome() {
System.out.println("看家");
}
}
//狸花貓
package d01.extendsStudy;
public class LiHua extends Cat{
}
//哈士奇
package d01.extendsStudy;
public class Husky extends Dog{
public void breakHome(){
System.out.println("拆家");
}
}
//測試類
package d01.extendsStudy;
public class Test {
public static void main(String[] args) {
// 建立物件並呼叫方法
// 建立布偶貓的物件
Ragdoll rd = new Ragdoll();
// 吃飯
rd.eat();
// 喝水
rd.drink();
// 抓老鼠
rd.catchMouse();
}
}
12.2.3 子類能繼承父類中的哪些內容
非私有 | private | |
---|---|---|
構造方法 | 不能 | 不能 |
成員變數 | 能 | 能(但無法直接使用,只能透過get,set函式使用) |
成員方法 | 能 | 不能 |
12.2.4 繼承中:成員變數的訪問特點
-
繼承中成員變數訪問:就近原則
現在區域性找,本類再找,都沒有就開始找父級,逐級往上
-
如果出現同名,且還想訪問固定未知的變數
package d01.extendsStudy1; public class Variable { public static void main(String[] args) { Zi z = new Zi(); z.test(); } } class Fu { String name = "FuName"; } class Zi extends Fu { String name = "ZiName"; public void test() { String name = "FunName"; System.out.println(name); // FunName System.out.println(this.name); // ZiName System.out.println(super.name); // FuName } }
12.2.5 繼承中:成員方法的訪問特點
12.2.6 繼承中:構造方法的特點
12.2.7 this、super使用總結
12.3 包、final、許可權修飾符、程式碼塊
12.4 抽象類
12.5 介面
12.6 多型
12.7 內部類
遺留問題
鍵盤錄入的使用問題
附加:
附1:類的區分
- Javabean類:用於描述一類事物的類。如,Student,Teacher,Dog等,書寫Javabean類的時候,要私有化成員變數, 書寫孔燦構造方法(可不寫),書寫全部引數的構造方法,針對每一個私有化的成員變數提供對應的get,set方法,如果有額外的行為,還需要寫對應的成員方法。
- 測試類:用來檢查其他類是否書寫正確,帶有main方法的類,是程式的入口
- 工具類:不是用來描述一類事物的,而是幫我們做一些事情的類
- 類名要見名知意
- 私有化構造方法(不允許外界透過工具類new一個物件出來,因為工具類主要提供工具方法,而不是建立物件)
- 方法定義為靜態方法(方便外界環境在不能new的情況下依舊呼叫工具類裡的方法)
已經看到p121