JavaSE
一、 基礎語法
1、 基本數據類型
1、
數據類型 |
字節數 |
二進制位數 |
byte |
1 |
8 |
short |
2 |
16 |
int |
4 |
32 |
long |
8 |
64 |
float |
4 |
32 |
double |
8 |
64 |
char |
2 |
16 |
boolean |
1 |
1 |
boolean類型的值只有true和false兩種邏輯值,在編譯后會使用1和0來表示,這兩個數在內存中按位算,僅需1位(bit)即可存儲,位是計算機最小的存儲單位。
數據類型char在中文編碼GBK-2312中占2個字節,在UTF-8中占3個字節。
2、判斷與循環
邏輯運算符 |
作用 |
& |
與作用,左右兩邊兩個判斷結果都為true就是true,否則是false |
| |
或作用,左右兩邊兩個判斷結果只要有一邊為true,結果就是true,否則就是false |
^ |
異或,你為true我就是false |
&& |
左右兩邊,左邊如果為false,右邊不執行,直接返回結果false |
|| |
同理:左邊如果為true,右邊不執行直接返回true |
第一種:
if(條件表達式){
語句塊1
}else{
語句塊2
}
第二種:
if(條件表達式){
語句塊1
}else if{
語句塊2
} else {
以上條件均不滿足而執行的默認的邏輯
}
第三種:
switch(被判斷的變量)
{
case 條件1:
執行條件1的邏輯
break;
case 條件2:
執行條件2的邏輯
break;
case n:
執行條件n的邏輯
break;
default:
以上條件均不滿足而執行的默認的邏輯
}
第四種:
While(判斷語句){
循環體
}
Do{
循環體
}while(判斷語句);
While是先判斷后執行,do while 是先執行循環體語句,然后進行判斷語句,就是說無論判斷是否為true都會至少執行一次循環體語句。
3、數組
1、 數組是對應的容器集合,需要存儲同類的數據,在一個容器中。
2、 數組使用中,需要規定數組的長度,長度從1開始,設置后長度不可變。
3、 數組使用中,定義數據的類型為:Object,可以存儲所有類型:,否則根據需要定義類型,可以是對象也可以是基本數據類型
4、 數組要想遍歷(一個個的拿到數據內的數據),我們需要for循環來完成,知道循環的次數,一個個的獲取。數組獲取中,如果超過角標,那么就會報錯:角標越
界異常:indexoutofboundsException,因為角標從0開始
5、 排序算法:(選擇和冒泡)
1、冒泡排序算法
2、選擇排序算法
二、 面向對象
1、 封裝
1、封裝屬性:對屬性的訪問權限進行了封裝,私有的只能自己用,公共的誰都可以用。
2、封裝方法:普通方法也可以使用關鍵字進行封裝,效果一樣,私有的方法別人不能用。
3、對私有的屬性,可以封裝一套獲取方法和設置方法,分別是set和get
Set別人設置我當前的私有屬性的數據。
Get別人獲取使用我當前的私有屬性的數據。
4、在創建對象的時候進行封裝:構造方法
創建對象的過程中,我需要創建出來的對象是空對象,那么就用空參構造方法。
創建對象的過程中,我需要創建出來的對象是帶有數據的對象,不是一個空對象,那么我們就使用有參構造方法來創建。
如果對象中不寫構造方法,默認就有空參,如果寫了那么就使用寫了的,如果只寫有參不寫空參,那么就無法使用空參創建對象。默認的空參在你寫了有參的時候就會消失,需要手動再寫空參才能正常使用。
5、構造方法和普通方法一樣,可以方法名相同,但是參數數據類型與數量不能相同,必須在同一個對象中,我們稱之為是方法的重載。
重載:方法名必須相同,參數類型不同。
重載:可以修改方法的訪問修飾符,可以修改返回類型,無返回還是有返回。
6、封裝四個關鍵字使用的范圍
位置 |
private |
默認的 |
protected |
public |
同一個類 |
是 |
是 |
是 |
是 |
同一個包內的類 |
否 |
是 |
是 |
是 |
不同包內的子類 |
否 |
否 |
是 |
是 |
不同包並且不是子類 |
否 |
否 |
否 |
是 |
注意:當前屬性如果需要完全給別人使用,我們就需要設置公共的:public
注意:當前屬性如果只能自己完成,別人不能使用,我們就需要設置私有的:private
注意:private 使用:方法:get方法與set方法,可以被別人使用。
2、 繼承
1、 繼承:子類繼承父類,子類可以使用父類的所有的非私有的屬性和方法
2、方法的重寫,需要注意事項:
1、方法名必須相同。
2、必須是繼承或者實現關系。
3、重寫方法傳遞的形參必須與父類的方法保持一致,不能設置其他形參。
4、重寫的方法,訪問權限封裝關鍵字:子類的訪問權限可以修改,但是權限的大小一定要比父類大。不能比父類小。
3、方法的重載和重寫的區別
1、方法的重寫:必須有子父類的關系,子類重寫父類的方法,提升方法的功能,重寫方法中,修飾符子類需要比父類更大不能更小,也可以相同。方法名必須相
同,參數和返回值也必須相同。
2、方法的重載:在當前自身對象中,提供多種相同的方法,但是有區別的是,修飾符可以不一樣、返回值可以不一樣、但是方法名必須相同、小括號內參數,參
數類型不同或者參數數量不同來區分。
一個是發生在自己當前對象的:方法重載:overload
一個是發生在子父類對象的:方法重寫:override
3、 多態
1、多態創建出來的對象,可以執行調用父類的非私有的屬性和方法。
2、使用多態,如果要想調用子類的方法,那么子類的方法,必須是父類重寫的方法。否則無法調用。
當前使用多態創建出來的對象,如果當前的方法,是子類重寫父類的方法,那么就優先調用執行。如果當前的方法,子類沒有重寫父類的方法,
那么調用的就是父類的方法。
3、多態調用執行:
1、多態優先調用子類重寫父類的方法。
2、多態可以調用父類的非私有方法。
3、多態可以調用父類的非私有屬性。
4、多態不能調用子類的非私有屬性。
5、多態不能調用子類的非私有方法。
4、解決多態不能調用子類的非私有屬性和方法。
如果使用多態想要調用子類的特有屬性和方法的話。我們需要將多態創建出來的對象,進行強制類型轉換。將父類轉換成子類。
5、多態使用的細節總結:
1、使用多態必須是有繼承或者實現關系的。
2、使用多態我們如果需要調用子類的方法,必須是重寫方法,重寫方法的權限最大。
3、使用多態創建出來的對象,不能調用子類的特有屬性和方法,如果真想調用,我們就需要使用到強轉。
注意:在強轉的過程中,大家很有可能會出現一個異常:ClassCaseException:類型轉換異常。
4、注意:為了避免后期大家出現類型轉換的錯誤,我們事先可以先測試判斷一下類型轉換是否正確:instanceof
5、當前我們可以使用到,關鍵字進行判斷,判斷出來的結果,就是正確或者錯誤,我們判斷當前轉換的類型,是否合格,如果合格我們就轉換,如果不合格我們
就不轉換,就能解決類型異常的問題。
4、 抽象類
1、抽象類:光定義方法但不實現方法。
2、抽象方法,只能出現在抽象類或者是接口中,不能出現在普通方法中。抽象方法:當前只定義,不實現。例:父親的願望需要兒子去實現(俗稱:負債子還)。
3、創建一個抽象類:關鍵字:abstract。
抽象類,其實和普通類類似,可以有屬性、構造方法、普通方法、get方法set方法等等。但是,抽象類中還可以定義抽象方法。
4、在抽象類中,定義抽象方法
5、子類如果實現的是抽象類,那么必須實現抽象方法(一定要對抽象方法進行重寫)
如果子類不重寫父類的抽象方法,就會一直報錯。
6、創建對象的過程中,抽象類是不允許被創建出來的
抽象的對象,是不允許直接被new創建的。
抽象類,如果要想創建,我們就需要使用對應的實現類(兒子創建)
7、 抽象類的出現:抽象類當中存在抽象方法,如果要想實現,那么就需要子類完成。但是抽象類,又不能直接初始化,還是得用多態來初始化。
多態的產生,其實有兩部分的原因:
1、 多態讓創建對象,變的更加的靈活,根據用戶的選擇可以動態的進行創建。
2、 抽象類與接口是不能直接被創建的,而是需要通過多態的創建方式,讓子類具體實現,完成創建工作。
8、抽象類總結:
1、抽象類不能被final修飾,因為抽象類必須要有兒子。
2、抽象類不能在方法中使用 final修飾,因為抽象類的抽象方法必須要被重寫。
3、抽象類可以繼承抽象類,所有的抽象方法需要在實現類中一起實現。
4、抽象類中可以有抽象方法,也可以有普通方法、屬性、構造方法。
5、 接口
1、定義接口關鍵字:interface
2、接口中方法都是抽象方法,不能有方法體。不能有普通方法,不能有構造方法。當前的接口中,只能有抽象方法,不能有實體方法。
3、定義接口中的屬性:接口中不能有變量,只能存在常量。當前的屬性也可以使用靜態來修飾。
使用靜態修飾的好處:接口對象名稱調用屬性可以直接調用。
4、接口能否被final修飾?
1、接口是不能被final修飾的。
2、接口中的方法不能被final修飾。
3、接口中的屬性可以被final修飾,因為默認就是使用的final。
5、使用接口:接口是不能直接被new出來的。所以當前必須先有實現類。
6、Java的關系映射:單繼承、多實現。
單繼承:對象與對象間,繼承只能繼承1次。
多實現:對象與接口,一個對象可以實現多個接口。
7、接口和抽象類的區別:
1、抽象類可以有普通方法和抽象方法。
2、抽象類中定義的屬性是變量。
3、抽象類可以繼承抽象類或者普通類。
4、抽象類可以實現接口,但是沒有必要。
5、抽象類不能直接創建,需要用多態的方法創建。
1、接口中只能有抽象的方法。
2、接口中屬性是常量定義。
3、接口可以繼承接口,但不能實現。
4、接口繼承是多繼承,抽象類繼承是單繼承。
5、不管是接口還是抽象類,對象不能使用final修飾。方法不能使用final修飾。
因為后期在Java中開發項目,項目后期肯定要維護升級的,我們如果使用抽象類,就只能單繼承,不方便維護,讓項目加大了局限性。而使用接口的話,實現的接口數
量不限,可以多實現,解決了項目后期更新的局限性問題。
理解:
抽象類就相當於是領導,領導定義任務,員工完成。
接口就相當於是規范,接口制定規范,所有員工需要遵守。
6、 關鍵字
1、 this關鍵字
this對象:this關鍵字就是當前對象的引用關鍵字,用來區分傳遞形參與當前對象內的參數區別開來。
2、 super關鍵字
1、構造方法中使用super:
Super必須放在前面。
Super需要帶有小括號。帶有小括號就會調用父類對應的構造方法。
2、super在普通方法中使用
Super如果在普通方法中使用,那么直接使用super即可,不需要添加小括號,不添加小括號的super,是直接引用的父類對象,不是構造方法。
3、 static關鍵字
1、static關鍵字修飾方法,我們無需new對象,即可通過類名調用方法。
2、static關鍵字修飾屬性,我們無需new對象,即可通過類名調用屬性。
3、原因:static修飾的屬性和方法,在生成.class文件的時候就會被初始化出來。
4、static可以設置一個靜態代碼塊:
Static{ }:運行的方式,是程序執行的時候,第一次就調用的,運行權限比構造方法還要大。程序一運行,第一個就調用的是靜態代碼塊。
使用場景:后期初始化數據的時候,我們會使用到。
5、static缺點:如果是static修飾的屬性和方法,聲明周期就會拉長,內存數據回收就會變得不方便,有些占用內存,后期在項目中,如果數據龐大的情況下,還是盡量少使用。
4、 final關鍵字
1、final可以修飾class屬性對象,被final所修飾的對象,將不能被繼承。
2、final可以修飾屬性,被修飾的屬性,就從變量變成了常量,不可修改。
3、final修飾的方法,當前的方法只能使用,不能被重寫。
7、 內部類
1、內部類:在當前的對象內,再創建一個對象,稱之為內部類
2、我們創建內部類對象規則:
內部類,必須在類對象的括號內創建,命名不能帶有小括號。
3、初始化內部類。
注意:因為當前的對象是內部對象,所以先要將外部對象創建出來,再來創建內部對象,外部對象創建內部對象中,使用到了調用,所以創建內部對象的時候,前面需要帶
上小點,進行調用。
4、內部對象,是否會生成.class文件:
會生成一個Animal$Cat.class文件,因為是否生成class文件,取決於是否使用了class關鍵字
5、內部類一樣和外部類使用,只是內部類是寫在對象內的。一樣也可以封裝、繼承、多態
6、匿名對象:就是沒有名字的對象,一般使用在創建對象的時候。
注意:當前調用的方法與創建的對象,只會執行一次,它是一次性寫法。因為沒有給對象在創建的時候命名,所以方法執行完,對象也會隨着消失銷毀在內存中。所以如果
需要再次調用方法,那么就需要重新再次創建對象。
7、匿名內部類:在當前類中創建一個類,但是不給名稱。(因為抽象類與接口不能直接被new,要先直接初始化其實也有方法,我們當前就需要使用匿名內部類)
8、匿名內部類,也會生成一個class文件,雖然沒有明文寫出,生成的class文件還是會出來,命名使用的是1命名。
三、 常用API
1、引用數據類型:
1、基本數據類型:8種:
整數類型:byte、short、int、long
浮點類型:float、double
判斷類型:boolean
字符類型:char
2、引用數據類型:9種:
整數類型:Byte、Short、Integer、Long
浮點類型:Float、Double
判斷類型:Boolean
字符類型:Character
字符串:String
3、字符和字符串的區別:
1、字符是基本數據類型,字符串是引用數據類型。
2、字符定義的字符可以轉換為對應的ascii表,對應的數字,可以進行加減乘除。
3、字符串因為是常量,數據是在常量池中,只能做對應的加法,是拼接。其余的減乘除都是不行的,因為String是不支持的
4、String對象,創建的幾種不同方式。
直接創建:從常量池就能直接拿到對應的常量數據
通過new關鍵字創建:常量池常量傳遞給堆,堆再給棧。
5、String創建的字符串都是常量,不能修改,修改的話就是重新在來生成一個,原有的就會等待回收機制回收。
6、String構造方法中,我們可以給空的、也可以給具體的String字符串、還可以給對應的數組讓數組對應的字符或者數字來生成一個字符串。
7、 自動裝箱與自動拆箱
基本數據類型,轉換為引用數據類型,自動裝箱。
引用數據類型,轉換為基本數據類型,自動拆箱。
2、StringBuffer和StringBuilder
1、String:字符串常量
StringBuffer:字符串變量
StringBuilder:字符串變量
2、線程安全
StringBuilder:線程非安全的
StringBuffer:線程安全的
3、三者使用:
1.如果要操作少量的數據用 = String
2.單線程操作字符串緩沖區 下操作大量數據 = StringBuilder
3.多線程操作字符串緩沖區 下操作大量數據 = StringBuffer
4、
1、StringBuffer對象,默認長度是:16
2、StringBuilder對象,默認長度是:16
3、Date
1、Date日期對象,我們就是通過它將對應的毫秒值轉化為我們看的懂的日期對象。
2、Date對象中,重寫了toString方法,里面含有對應的返回日期格式。我們看完后,查看到了對應的英文字母,這些就是定義日期格式的關鍵字符。
3、當前我們如果需要自己定義日期顯示的樣式,我們就需要對應設置自己所需要的字母關鍵字符,但是Date里面是沒有給我們提供設置方法的,我們需要使用到日期的幫助類:SimpleDateFormat
4、SimpleDateFormat對象,對Date日期對象進行了一個顯示內容的封裝,讓當前的日期,可以根據用戶自身的需求進行自定義格式。但是自定義格式中,我們需要通過字母將格式設置完成后,才能使用。
5、當前Date與SimpleDateFormat對象兩個相結合,最終就能得到我們想要的日期格式,日期格式顯示出來的內容,就是根據毫秒值來轉換的。
6、日期為什么需要使用毫秒值,避免時間重復,時間計算是需要非常精准的。因為任何項目如果時間戳出了問題,就會產生不可逆的異常。
四、 集合
1、 三個集合的區別
List |
ArrayList |
底層是數組 |
查詢速度快,增刪改慢 |
線程不安全 |
效率高 |
LinkedList |
底層是雙向鏈表 |
增刪速度快,查詢慢 |
線程不安全 |
效率高 |
|
Vector |
底層是數組 |
查詢快,增刪慢 |
線程安全 |
效率低 |
|
ArrayList 初始容量為10,自增長度是(10*3/2)+ 1。 Vector 內部數據數組的大小為10,其標准容量增量為零。 |
Set |
HashSet |
底層是HashMap |
存取速度快, |
線程不安全 |
無序,不可重復 |
可以存儲null,但只能放入一個null |
TreeSet |
底層是紅黑樹 |
排序存儲 |
線程不安全 |
有序,不可重復 |
不可以存儲null |
|
HashSet其底層HashMap實例的默認初始容量是16,加載因子是0.75 |
Map |
HashMap |
底層是Hash表(數組+鏈表) |
效率高 |
線程不安全 |
鍵值可以存儲null,但只能存儲一次,不然會被覆蓋 |
HashTable |
底層是Hash表(數組+鏈表) |
效率低 |
線程安全 |
不可以存儲null |
|
HashMap 默認初始容量是16,加載因子是0.75 HashTable默認初始容量是11,加載因子是0.75 |
2、 集合的關系圖
1、匯總:
Collection:是集合中的一個接口父類,它是一個分支,子類實現接口中:List和Set
Map:也是集合中的一個接口父類,子類中是:HashMap、HashTable
2、Map接口集合,與Collection區別:
Map結構分為:k v,俗稱鍵值對。
K:key:鍵
V:value:值
在map集合中,k就是鍵,是主鍵的意思,不能重復。V就是值,值可以重復。
在List集合中,角標就是鍵,里面的內容就是值。角標從0開始,沒有重復的。
五、 IO流
1、我們所學習的所有IO:
FileWriter:文件的字符輸出流,是Writer的子類。
FileReader:文件的字符輸入流,是Reader的子類。
BufferedWriter:字符高效輸出流,當前默認有緩沖區。
BufferedReader:字符高效輸入流,當前默認有緩沖區。
FileOutputStream:文件字節輸出流,當前是萬能輸出流。
FileInputStream:文件字節輸入流,當前是萬能輸入流。
BufferedOutputStream:文件高效字節輸出流,當前默認有緩沖區。
BufferedInputStream:文件高效字節輸入流,當前默認有緩沖區。
ObjectOutputStream:對象輸出流
ObjectInputStream:對象輸入流
只能將支持 java.io.Serializable 接口的對象寫入和讀取到流中。
2、文件的嵌套復制,遞歸
在文件夾復制的工作中,文件夾中還有存在子文件夾,嵌套存在深度不一致多,有的多有的少。我們需要復制過程中考慮全面,就需要將代碼嵌套比較的多,效率極低。
當前解決的辦法:使用的是遞歸來解決文件夾嵌套創建的問題。
遞歸的好處:不斷調用自身,進行文件夾創建。
遞歸使用的注意事項:
需要遞歸的過程中,設置出口,停止定義,否則就會一直調用導致堆棧溢出。
遞歸的算法:當前重復調用方法,直到拿到預期的目標跳出遞歸,進入出口。
遞歸的使用中:
入口:調用自身。
出口:得到預期的目標,跳出進入出口,結束調用自己。
3、 IO流,分為字節流和字符流
1、字節流和字符流
字符流:只能對文本文檔操作的流對象,因為當前讀寫設置的是char類型的容器。
字節流:是萬能流,不僅可以對文本文檔操作,還能對其他類型的文檔操作,比如圖片、視頻、音頻等等,因為當前讀寫設置的容器類型為byte類型,根據字符的編碼存儲編碼的序號數字,進行轉譯。
2、字節流與字符流,當前的效率字節流要快於字符流。
字節流復制文件,一個需要800多毫秒即可,但是字符流復制文件,一個需要7秒,同樣的大小200多MB的文件。
1、 在公司中開發,我們常用的是字節流,因為字節流對應功能局限性小,效率高。
2、 當前我們學習字符流和字節流中,我們還學習了對應的高效輸出輸入流。
3、 字節高效的輸入輸出流,要快於普通字節流,快的速度800毫秒可以縮短到300毫秒。
字符流也是同理,高效的要高於普通的,因為高效的可以讀取一行,直接寫入,需要換行寫入的時候可以插入換行。
3、為什么高效的要快:因為當前底層設置了緩沖區,我們可以創建高效流的同時使用默認緩沖區,或者自定義緩沖區,我們一般使用默認即可,因為默認已經足夠我們使用了。
默認緩沖區大小:8192字節。
六、 多線程
1、 多線程的開啟方式
1、方法一:自己創建一個對象,繼承多線程對象,進行創建多線程。
2、方法二:通過實現一個接口Runnable接口,讓多線程對象使用。
2、 多線程設置同步鎖
1、方式一:使用同步代碼塊:關鍵步驟上鎖
注意:鎖對象必須是一致的,一般使用class文件,保持一致。或者使用單例設計模式創建對象。
2、方式二:同步方法:將整個方法進行上鎖
注意:當前線程可以開啟多個,但是runnable實現類必須只有一個,不能實現多個實現類,否則同步方法無效
方法三:靜態同步方法,所有的對象都上鎖,一鎖鎖所有
注意:當前如果要實現多個runnable實現類,不同的對象間使用方法鎖的話,可以使用靜態同步方法,這樣的話就能夠解決方法二不能鎖住的問題。
3、方法三:靜態同步方法,所有的對象都上鎖,一鎖鎖所有
注意:當前如果要實現多個runnable實現類,不同的對象間使用方法鎖的話,可以使用靜態同步方法,這樣的話就能夠解決方法二不能鎖住的問題。
3、 兩種設計模式
1、 單例設計模式
懶漢式:
餓漢式:
2、 生產者與消費者模式
1、生產者生產數據到緩沖區中,消費者從緩沖區中取數據。
如果緩沖區已經滿了,則生產者線程阻塞;
如果緩沖區為空,那么消費者線程阻塞。
2、wait:等待方法
被等待的線程是自身喚醒的,必須得依靠別的線程或者對象喚醒,喚醒通過鎖對象調用喚醒方法。
3、notify:喚醒方法(喚醒單個)
喚醒單個:隨機喚醒等待的線程中的一個線程
4、notifyAll:喚醒方法(喚醒全部)
喚醒全部:將當前所有等待的線程進行喚醒,喚醒后不一定所有線程都執行,具體誰執行還需要看CPU給誰分配了資源搶占了鎖對象。
注意:當前鎖對象如果不是同一把鎖,就無法喚醒,同時也可能產生一直等待的狀態,線程堵塞
5、sleep方法,當前休息睡眠一定的時間后,自己就能夠清醒過來,進行繼續運行。
區別:等待喚醒機制,如果當前處於等待的狀態,就會釋放鎖對象,丟給其他對象使用並且執行,當前自身處於等待不執行的狀態。 睡眠方法,則不同,當前線程如果是睡眠方法,那么在睡眠的過程中是不會釋放鎖資源的,等清醒后,繼續操作執行,直到執行結束,結束操作,釋放鎖資源,提供給其他對象使用。
七、 網絡編程
1、網絡編程的三要素:IP地址、端口號、網絡協議。
2、網絡協議:底層協議:UDP、TCP
UDP:直接連接的網絡協議,一般使用的場景:視頻、語音、聊天室。
TCP:三次握手連接,一般使用的場景:傳輸圖片、發送聊天文字等等。
區別:
UDP:效率快,但是數據丟失無法找回,數據傳輸不穩定。
TCP:效率相對慢,傳輸的數據,穩定丟失比較低。
使用網絡協議傳輸的過程中,我們基本上使用的都是流對象傳輸。
八、 反射與正則表達式
1、反射
1、對象反射的方式一共有:三種
第一種:創建出來對象,通過對象的引用獲取。
第二種:通過類的包名 + 類名直接尋找。
第三種:直接通過類名調用class關鍵字。
2、暴力訪問,將setAccessible的狀態設為true,然后就可以獲取私有的屬性和方法。
2、正則表達式
1、使用一個正則對象
|
matcher |
|
matches |
使用示例: