JavaSE总结笔记
JavaSE筆記
??快捷鍵集合
1.psvm
public static void main(String[] args) {}2.sout
System.out.println();3.Shift+Ehter 換行
4.Shift+F6 重命名
5.Alt+Shift+Enter 數據類型轉換
6.IDEA菜單欄Code→Generate→全選 生成構造器
??經典算法思想
1.冒泡排序
確定迭代次數是array.length - 1,確定每次迭代將最大值放在最后邊
確定每次比較的次數array.length - 1 - 此次迭代次數
優化:
如果本身有序,可以設置flag,每次迭代但凡沒有發生交換則都有序
如果某次迭代內后方全部有序,可減少區間長度
2021年11月11日
1.環境安裝
1>IntelliJ IDEA 2020.1.3
2>JDK——jdk-8u131-windows-x64
3>Git
2.基礎知識
1>計算機
-
hardware:CPU(只和內存聯系)、內存、I/O
-
software:操作系統
2>IDEA
源碼文件HelloWorld.java,經過編譯(compile),生成類文件/字節碼(byte code)文件HelloWorld.class,這種類文件可以在虛擬機上執行。class并不直接與機器的操作系統相對應,而是經過虛擬機間接與操作系統交互,由虛擬機將程序解釋給本地系統執行,所以JVM是整個Java實現跨平臺的最核心的部分。JDK中包含了JRE,JRE又包含JVM。
- javac:java源文件、類文件(字節碼文件)編譯器(compiler)
- JVM(java virtual machine):java虛擬機,運行字節碼的一個程序
- JDK(java development kit):java開發工具包,包含JRE、java工具(javac/java/jdb等) 、基礎類庫(Java API)
- JRE(java runtime environment):java運行時環境
- Intellij IDEA:一款IDE的產品
3.使用IDEA創建項目的過程分解
1> 新建工程
經由IDEA(程序)指定位置新建目錄、新建配置文件
2> src新建一個HelloWorld 類
IDEA 指定位置(src目錄)HelloWorld.java,文件中填充了一部分默認內容
3> IDEA 把代碼寫入 HelloWorld.java文件中
4> 點擊run
- 編譯 IDEA根據JDK所在目錄,找到javac進行編譯,HelloWorld.class
- 運行 IDEA根據JRE所在目錄,找到java運行類文件
4.類 class
-
類名==java文件名,可以使用Shift+F6 / rename改名稱
-
命名要求:
- 不能以數字開頭
- 不能含有特殊符號(字母、數字以外的符號,下劃線是允許的)
- 不太建議使用中文類型
類名通常為HelloWorld,方法名、變量名通常為helloWorld,包名為hello_world
-
一個java源文件中只能有一個public類
-
類中包含方法,方法內包含語句
5.數據 data
全部是內存上的數據
1>數據類型
-
基本數據類型**(8類)**
-
數值類型**(7類)**
- 整型 byte short int long
- 字符型 char,可以認為是一種有特殊地位的整型
- 浮點型 float double
-
布爾類型**(1類)**
? boolean,值為 true / false
-
-
引用數據類型**(3類)**
- class類型 String s;
- interface類型 Flyable f;
- array類型 int[] t;
字節數:一字節=1byte=8位=8bit
| 字節數(byte) | 1 | 2 | 4 | 8 | 2 | 4 | 8 | 1 bit |
不分有符號與無符號類型,最高位1代表負數,0代表正數。
使用Integer.MIN_VALUE可以獲得int類型可以表示的最小十進制數:
int min = Integer.MIN_VALUE;2>變量(本節重點)
👉跳轉2021年11月25日
-
變量==內存,變量屬于內存上的一塊區域
-
定義
- 變量類型 變量名稱
- 變量類型 變量名稱 = 值
變量名稱表示在內存的哪部分,變量數據類型決定變量內存的區域大小
-
種類
根據在代碼中定義的位置,有不同的種類,決定了變量的不同:
作用域(scope)——代碼視角
生命周期(life)——內存視角
-
全局變量
-
局部變量(local variable)
變量的作用域(scope)在{ }內,但對于{ }外定義的變量在{ }內進行的賦值是有效的;
局部變量語境下,如果一個變量只定義,沒有賦值,無法直接使用(取其值)。
-
-
使用
- 賦值(出現在=的左邊)
- 取值(出現在=的右邊)
3>基本數據類型的一定規則(類型轉換和類型提升)
6.字面量 literal
int a = 9;內的9就是字面量
字面量屬于數據,默認類型是int。
| 9 | int |
| 9L / 9l | long |
| 9.f / 9F | float |
| 9. | double |
| true / false | boolean(不允許boolean a =1) |
| ‘a’ | char |
| ‘xx’ | String |
整型字面量有不同的進制表示:二進制0b10,八進制0o10,十六進制0x10;或用科學計數法表示1.3e8,即1.3x10^8。
2021年11月14日
1.賦值操作 =
【等號左邊:以變量為代表的內存空間】a = 3【等號右邊:值,可以是字面量、變量、表達式】
通過變量去保存一個字面量
2.類型轉換(type cast)
1>等號兩邊類型一致
2>類型不一致——類型轉換
①類型提升 以參與運算的最高類型為主
②數值類型轉換
-
int a=(int)10L
-
轉換規則
char
double > float > long > int > short > byte
- 小賦值大 默認成立
- 大賦值小 默認不成立
- 數值類型和Boolean類型、引用類型無法轉換
-
快捷鍵 Alt+Shift+Enter
字面量變量默認為int,但仍可以賦值
byte b = 1; short s = 2;這是java基于字面量變量的特殊規則,byte為-128~127,所以可以賦值[-128,127]的任何數
int c = 1/3; //int類型除以int類型,此處得0比如 1/3=0.333333,默認向下取整為0
final可以修飾數據類型,只能被賦值一次
大小寫轉換 'y'+'A'-'a' = 'Y'
3.字符串 String
- 不是基本類型,是引用類型
- s+1表示的是字符串拼接操作
- 與基本類型不能相互轉換
4.運算符
運行錯誤
- 編譯錯誤 不符合語法規則,IDEA會提示
- 運行時錯誤 程序運行期間會拋出異常,但符合語法規則
-
a++
int a = 1; System.out.println(a++); //輸出結果為1,先賦值再加1 -
邏輯運算符
- 運算都是Boolean類型
- 遵循短路求值,比如或運算中,只要有一個算出來為false,就不進行后來的運算
-
位運算
- &
- |
- ~
-
移位操作
- 0b101 >> 1 0b10 可以視為a/2
5.邏輯控制語句
-
順序結構
-
分支結構
- if-elseif-else語句 無if(a)的條件
- swtich-case-break-default語句
-
循環結構
break 跳出循環
continue 跳過這次循環,開始下次循環
- while語句
- 右鍵點擊斷點,設置條件,然后點擊運行至下一斷點處,可以跳過一部分循環
- for語句
- do-while語句
- while語句
作業
- Java標識符由字母、數字、下劃線“_”、美元符號“$”或者人民幣符號“¥”組成。
首字母不能是數字,不能是關鍵字,且對大小寫敏感。
- 閏年
閏年分為普通閏年和世紀閏年。
普通閏年:能被4整除但不能被100整除的年份為普通閏年。
世紀閏年:能被400整除的為世紀閏年。
2021年11月16日
1.輸出
System.out.println(); //方法調用system,只能有一個參數 System.out.print(); //輸出不換行 System.out.printf(); //format格式化輸出,可以有多個參數,且參數類型不確定。//不換行,使用與C語言相同//但可以使用%n替換\n,\r是回車2.輸入
- 使用scanner掃描器
| hasNextLine | 行為單位 |
| hasNext | 以空格\t分割的單詞為單位 |
| hasNextInt | 以空格\t分割的單詞為單位,但轉為整型 |
| hasNextLong | |
| hasNextDouble |
- hasNext()為true時,nextInt()才可以取值
3.隨機數
- Java中的隨機數都是偽隨機數,Random random = new Random(2021);中2021為seed,此時固定時生成的隨機數不變。
- Random和Scanner都是引用類型。
4.方法 method
1>定義
-
要在類里定義,不能在其他方法里定義
-
public static 返回值類型 方法名稱(形參列表){ 語句 return語句}
此處的參數列表是形參,形參其實是一種特殊的局部變量
-
無返回值可以將返回值類型設為void,return后的語句不能執行也不允許寫
throw new RuntimeException("此處可以寫提示");與return類似,此語句之后也不允許執行或寫語句
-
方法沒有調用,里面的語句永遠不會被執行,main方法除外
-
同一個類下,暫時不允許同名方法
2>調用
-
方法的調用實質是值,能出現值的位置,即可進行方法的調用,并且方法可以嵌套調用
-
變量類型 變量名稱 = 方法名稱(實參)
-
隱含的賦值操作
- 實參賦值給形參
- 方法調用的結果賦值給返回值
- 返回值賦值給調用方法的變量
-
在同類調用時可以直接寫方法名稱,在其他類調用寫類.方法名稱
2021年11月18日
1.包 package
- 用來放類的組織單位,包(文件夾)中含有很多的類(文件)
- 通過package聲明決定該類屬于哪個包,類的實際全名稱為 包名.類名
- 使用某個包下的類方法
- import 包名.類名;
- import 包名.*;
- 包名.類名.方法
2.git的使用
歷史博客《如何將IDEA文件提交至Gitee倉庫》
3.方法的調用棧 call stack
-
先進后出
-
主要用于表現此刻方法的調用關系
-
棧幀(stack frame):每層元素
java中的棧(調用棧)、棧幀(frame)都是JVM管理的內存的某個名稱
-
內存管理
內存(硬件)→OS→JVM→棧區(由棧幀組成:每個棧幀對應一次方法調用)
-
局部變量(包含形參)
-
在該變量對應的方法的某次棧幀上(方法的每次被調用,都有一個唯一的棧幀,方法執行結束,棧幀結束)
-
局部變量的生命周期
開始于方法開始執行:JVM 為本次方法允許分配好了棧幀
結束于方法執行結束:JVM 將方法執行中用到的棧幀回收 -
無論是基本數據類型還是引用類型,形參的改變不會影響實參(java中全部是傳值調用)
-
-
2021年11月21日
1.方法重載 overload
C語言中一個編譯單元(一個C文件)內不能出現同名的函數
Java中允許一個編譯單元(一個Java類)中可以出現相同的函數(方法),但要求參數列表不同
-
方法的簽名:Java編譯單元中唯一確定方法的標識
-
簽名 = 方法名 + 參數列表
只要求形參的類型不同,不要求形參的名稱不同
簽名不包括返回值類型,所以返回值類型相不相同沒有關系
-
2.靜態屬性
靜態屬性、類變量、靜態變量是除了局部變量之外的另一種變量種類
- 定義位置:類里但在方法外
- public static 數據類型 變量名 = 字面量變量;
- static{…}
- 按順序執行
- 作用域:在整個類的內部是有效的(大括號內)
- 生命周期:伴隨著類在運行中的生命周期而運行的
- 初始化問題:伴隨著類的生命周期,所以它在類加載的過程中就初始化完成,會在Main方法使用之前
- 默認值是0的變形:0、false、null
- 通過類名.變量名使用別的類下的靜態屬性變量
3.類的加載過程
將屬于一個類的數據(以類文件為代表)從硬盤上加載到內存中
-
某個類被用到的時候才加載
類被用到(類名.*):
類內方法被用到的時
用到類的main方法時
用到類的靜態屬性時
-
加載的時候被加載的數據
- 靜態屬性
- 方法→語句→字節碼指令
-
被加載到方法區
JVM中存在棧區和方法區
4.訪問權限(訪問限定符)
-
public:所有人都可以使用
-
protected:同一個包下的子類可以使用,子包下的子類中也可以使用,不同包下的子類中也可以使用,比包訪問權限要大
-
不寫,即default level(也稱為包訪問權限):同一個包的子類可以使用,否則就算是在子包下的子類中也不可以使用
-
private:只有自己類的內部可以使用
-
可以出現的位置:
- 類的內部、用來修飾 類變量、方法
- 類 不可以用private
5.數組 Array
1>數組
-
一組具有相同類型的元素的集合
-
定義 int[] a
-
使用:只能用于初始化
int[] a = {1,2,3,4,5}; //定義一個變量a,其類型是數組 //該數組的元素類型是int //并且進行了初始化操作 //該數組的大小已經確定為5 //該數組的元素分別為1、2、3、4、5Random[] b={new Random(...),new Random(...)};//這種使用是錯誤的 int[] a; a[] = {1,2,3,4,5}; //可以使用以下語句 int[] a = new int[] {1,2,3,4,5};//只規定長度,則默認為0的變形 int[] a = new int[3]; //等價于 int[] a = new int[] {0,0,0}; -
數組的長度一旦確定后就不可以更改了
//這是新創建了一個數組,用之前的數組a來使用 int[] a = new int[3]; a = new int[5]; -
數組的下標 index
- 類型:int
- 范圍:[0,數組的長度)
-
遍歷數組:從前到后訪問數組中的每個元素
- 需要知道數組的元素個數:a.length
2>引用和對象
- int[] a = {100,200,300};
-
a 引用 ?
-
{100,200,300} 對象 ?
每個對象都有自己的hash值(對象的指紋),對象不同,一般指紋不同
-
- 引用類型——形參的改變不會影響實參,但是
3>使用中常見的兩個異常
-
java.lang.ArrayIndexOutOfBoundsException
使用的下標不是合法下標時
-
java.lang.NullPointerException
對一個值是null的引用做解引用操作時
int[] a = null; 讓a引用不關聯(指向)任何對象
解引用:通過引用要去動對象中的數據,比如a.length、a[0]
4>數組的操作函數
| sort(array) | 對整個數組排序 |
| sort(array, int fromIndex, int toIndex) | 對數組的[fromIndex,int toIndex)范圍內進行排序 |
| binarySearch(array,key) | 使用二分查找算法搜索指定數組的key |
| equals(array1,array2) | 判斷兩個數組是否相等 |
| fill(array,element) | 使用element填充數組 |
| fill(array, int fromIndex, int toIndex,element) | 使用element填充數組的[fromIndex,int toIndex)范圍 |
| copyOf(array, int newLength) | 復制數組到一個長度為newLength的數組中 |
| copyOfRange(array, int fromIndex, int toIndex) | 將指定數組的指定范圍復制到新數組中,fromIndex不可以越界,toIndex可以越界,沒有的用0補全 |
| toString(array) | 返回指定數組的內容的字符串表示形式 |
2021年11月23日
1.多維數組
-
定義
long[][] a; 數組的類型是引用類型long[]
//long[] b; 數組的類型是long
2.面向對象 OOP
-
定義
對象:把一些相關屬性一一綁定
-
三個層次
- 概念層 學生
- 邏輯層 檔案,包括學生姓名學號專業
- 物理層 在內存中是怎么回事
3.類的第二大作用
- 類是構造對象的模板
1>屬性
-
定義
//類的定義 class Person{//屬性的定義String name;int age; } //實例化對象的語法 Person p = new Person(要調用的構造方法的參數列表); //通過引用使用引用指向對象的屬性 p.name = ...; ... = p.name; -
作用域:類內
-
屬性的初始化規則(4種)
執行順序為:默認值規則 → 定義時初始化規則和構造代碼塊規則按書寫順序 → 構造方法規則
-
默認值規則:不初始化則默認為0的變形
-
定義時初始化規則
class Person{String name = 'aaa';int age = 18; } -
構造代碼塊規則
{//類內,方法外//... } -
構造方法規則(構造器)
類似于方法,但是:
? 沒有返回值類型的聲明
? 構造方法的名稱==類名
? 構造器重載
class Student{//無其他構造方法會默認補此部分,內部為空public Student(){//...}//相當于方法重載public Student(String a){//...} }
-
2>this
-
作用
-
引用,類型就是當前類
指向當前對象:構造器種this指向的就是當前正在構造的對象
-
在一個構造方法中調用另一個方法
public Person(){this(17);//調用有參構造器 } public Person(int a){//... }
-
3>getter & setter
權限控制:權限最小原則
只讀不改 getter
2021年11月25日
行為:面向對象中的一個焦點,在Java中以實例方法的形式體現
實例方法:定義語法和之前一致,除了不要加static;
? 可以直接訪問屬性(和構造方法類似)
1.方法
1>靜態方法(類方法) 加static修飾——不可以訪問屬性,不可以使用this
2>普通方法(實例方法) 不加static修飾——可以訪問屬性,可以使用this
? 實例方法的調用,必須依賴一個對象(通過引用)的存在,如引用.普通方法()
| 方法內部 | 有this 可以訪問屬性 可以調用普通方法 | 沒有this 不能訪問對象的屬性 不能調用普通方法 |
| 方法外部 | 對象的引用去調用 “需要傳入一個this" | 可以直接調用 “不需要傳入this" |
在靜態上下文(static context)中無法直接調用普通方法、訪問對象屬性。
static的理解:
**加了static,只和類有關,和對象無關。**反之,不加static,和本來的對象息息相關,不論屬性和方法都是屬于對象的。
變量
| 局部變量 | 跟著方法運行走 | 棧幀>棧 |
| 類變量、靜態變量、靜態屬性 | 跟著類的加載卸載走 | 類>方法區 |
| 實例變量、屬性 | 對象實例化完成后出現,對象回收后消亡 | 對象>堆區 |
靜態方法和普通方法都在方法區
??OOP
三大特性:封裝(所以要設置訪問權限)
概念層
現實生活中,萬物皆對象(比如人物、進程等)
邏輯層
- 存在開發人員腦海中的世界,不止可以用Java實現
-
實際是對現實中一類有形或無形的概念的特征(特征表現為屬性)抽取(對其行為的抽取表現為方法),比如人(人都有四肢、五官)、葉子
- 對象的正確性判定
對象職責不同,方法不同,比如一個人求職或者學習,他 學習的方法是不同的
- 變成代碼的部分
物理層
對象在堆區
對象在堆區是如何存放的
對象是如何構建出來的
Person p = new Person();3 1 2 //大體上有三個步驟 //1. //通過類中的信息計算對象的內存大小(隱含著用到了類) //在內存(堆區域)由JVM分配空間 //全部用0初始化 //半成品對象構建完成 //2執行初始化過程 //對象實例化→加載方法→調用初始化語句 //對象實例化完成 //3引用賦值對象的死亡(不嚴謹):沒有任何引用指向它,就可以視為死亡
2021年11月28日
1.深淺拷貝
-
引用賦值 2
-
淺拷貝賦值
-
藕斷絲連似的賦值
-
對象內的引用指向的對象相同
-
-
深拷貝賦值
2.線性結構 List
邏輯層:都屬于線性結構
物理層:分為順序結構和鏈式結構,也就是順序表和鏈表
線性結構:
-
整體結構一般記為容器
-
裝在容器中的單獨的數據,稱為元素、項、數據、值
-
除了第一個元素和最后一個元素之外,其他元素都有共性,即有前元素和后元素
- 第一個元素沒有prev,有next,記為first、head
- 最后一個元素沒有next,有prev,記為last、tail
-
只有在線性結構中,下標才有意義,才討論第幾個元素,下標是表示第n個的代碼表示,所以在線性結構中才有排序的含義
-
數組也算一種比較特殊的線性結構,在保存元素時,數組允許出現空洞,線性結構不允許出現
1>順序表 ArrayList
順序表對象(在數組對象的基礎上構建的),多加了自行控制容量的職責(表現為方法)
下標與元素個數size有關,與容量array.length無關
long[] newarray = Arrays.copyOf(array,newlength);//進行擴容時間復雜度:
- 尾插尾刪 O(1)
- 根據下標插入刪除時 O(n)
- get(index)/set(index,e) O(1)
- 查找 O(n)
2>鏈表 LinkedList
??復雜度 complexity
- 一個評價程序(算法)好壞的標準
- 從兩個維度進行評定:
- 運行速度——時間復雜度
- 占用空間——空間復雜度
1.時間復雜度 **O(1)< O(log(n)) < O(n) < O(n)*O(log(n)) < O(n^2)**前可行< O(n^3) < O(2^n)
直接掐表的缺陷:影響因素太多,無法控制變量
前提:給定CPU之后,單位時間內執行的指令條數基本恒定
所以,衡量算法的運行時間轉換為衡量算法的執行指令個數
前提:Java中的基本指令(O(1)的語句)可以近似地看作指令的代替
即使固定算法,隨著算法處理的數據規模的不同,算法需要的語句數也是不同的。比如冒泡排序改變數字個數。
所以:我們希望得到的時間復雜度是一個語句個數關于數據規模的函數關系 基本語句個數 = f(數據規模)
- 只保留函數關系中的最高次項
- 把保留的項的常數系數變成1
步驟:找最壞的情況(去掉優化)、確定數據規模n、確定函數關系、大O表示法
時間戳:從1970-1-1 格靈威治時間到某個時間經過的秒數
long b = System.currentTimeMillis(); //以毫秒為單位的時間戳//current 當前的Millis毫秒規模n擴大多少倍,消耗的時間就擴大大O內的函數關系倍
假設在某臺計算機上,冒泡排序50個數,耗費6秒的時間,冒泡排序500個數需要多長時間?
O(n個2) n的規模擴大了10倍,消耗的時間10^2 600s
單路遞歸一般是O(n)
二路遞歸(漢諾塔和斐波那契)一般是O(2^n)
數組的用下標訪問時間復雜度為O(1)
2.空間復雜度
單路遞歸一般是O(1)
二路遞歸一般是O(n)
2021年11月30日
1.鏈表 LinkedList
結點 node
- 元素
- 下一個結點的位置(引用)
通過頭結點代表鏈表,即使沒有頭結點
等號左邊一定是引用,等號右邊一定是對象
作業:寫一份順序表代碼
2021年12月2日
1.鏈表的特殊情況
- empty鏈表(空鏈表)
- 只有一個結點的情況
- 頭結點、尾結點
2021年12月7日
1.鏈表操作
- 翻轉、刪除、合并、刪除重復、分割
- 復雜鏈表復制
2.鏈表對象
雙向無頭不循環
- 屬性、方法、一致性
- 分情況考慮:
- 空鏈表、有一個結點的鏈表、其他情況的鏈表
- 頭結點、尾結點、中間結點
- 重點:根據下標輸入、刪除
3.內部類
- 靜態內部類——用來控制權限
- 普通內部類
??static
1.靜態方法
2.靜態導包,省略Arrays
import static java.util.Arrays.*;2021年12月9日
1.繼承
概念層的 is - a 關系
類A(動物)→ 類B(貓🐱)
類B繼承類A,類B派生于類A,類B擴展于類A
類A:父類(parent class)、基類(base class)、超類
類B:子類(sub class)、派生類(derived class)
class B extends A{//B的方法//IDEA提示的加粗的方法是自己的方法,其他的為繼承的方法。 }-
繼承關系
- 不同類可以繼承一個類,但不支持一個類繼承多個類(多繼承)
- class A{}隱含著類A繼承自java.lang.Object類
-
邏輯上,子類對象中包含一個"父類對象",無論有沒有權限訪問。即類B有類A的全部方法和屬性,只是一些可以訪問,一些不可以。
-
子類對象實例化之前,必須在子類的構造方法中,調用父類的構造方法
- 通過super()調用
- 通過super可以明確訪問父類,無歧義時通過this也可以訪問父類
- super看到的是父類允許子類看到的(有訪問權限的)
- 當父類有無參構造方法時,super()可以省略
- 通過super()調用
-
子類加載前需要先把父類加載好,不管子類的構造器在哪里,都要先加載好父類
-
構造代碼塊在實例化的時候執行的
-
多態:對象有多種形態,比如動物有貓、狗等多種類型
-
方法重寫時,即使是父類中的this.也是new的對象類型的this對象
??能使用哪些方法,看引用類型;使用的是哪個對象的方法,看new的對象類型
- 向上轉型是自然的,向下轉型是有風險的,要進行風險測試if(Pet instanceOf Dog)才能轉
2022年01月04日
1.復習
-
初始化順序(父類在子類前)
- 類的加載化的初始化順序
- 對象實例化的加載順序
-
多態的語法知識
2.abstract
1>抽象類
-
抽象類被剝奪了實例化對象的能力(比如大的概念動物類),是用來繼承的
可以引用Animal animal;,不能實例化對象new Animal();
-
抽象類與普通類的區別
抽象類不能實例化對象,允許出現抽象方法
“有抽象方法的是抽象類”是錯誤的
-
Java賦予了抽象類新的能力
允許定義一些方法,但不實現(沒有方法體,只是聲明,留給子類去必須重寫,稱為抽象方法)
2>抽象方法
-
抽象類與抽象方法的關系
抽象方法只能出現在抽象類中,不能出現在普通類中
“凡是抽象類中一定要出現抽象方法”是錯誤的
-
例子
比如線性表(抽象)類定義’頭插’方法(其中包含’按照下標插入’),鏈表和順序表中’定義按照下標插入’方法
3.final
1>最終變量
- 只能賦值一次
2>最終類
- 通過final修飾的類,無法被繼承
抽象類、普通類、最終類都允許出現一種方法——最終方法
3>最終方法
- 通過final修飾的方法,不允許被重寫
- 允許出現在任何類中,出現在最終類中意義不大(因為最終類無法被繼承,其中的方法自然不會被重寫)
4.類的三種職責
- ①放置靜態屬性/方法的位置
- ②實例化對象
- ③被繼承
| 抽象類 | ③ |
| 普通類 | ②③ |
| 最終類 | ② |
5.接口 Interface
可以理解為一種極端的抽象類(全部只有抽象方法的抽象類),所以不可以被實例化對象,它描述的是一個概念
-
不會出現屬性(其實可以出現,但是是特定的)
-
只能出現方法(默認是抽象方法,并且被public修飾)
-
與抽象類的差異
-
類描述現實中的一類事物:抽象事物(比如動物,線性表)和具體事物(狗、順序表);
接口大多時候只是一組能力的聚合,描述具備某種能力的東西(比如會飛,會跑),具體是什么事物不知道
-
類可以被繼承,只允許單繼承,extends
接口是用來被實現的,允許一個類同時實現多個接口implements,并且接口本身也允許多繼承自其他接口
-
6.Cloneable 接口
具備克隆能力,拷貝的對象是淺拷貝的
當某個對象被Cloneable修飾時,JVM內部會對其特殊處理,允許
SomeClass sc = new SomeClass(); SomeClass copy = clone sc; //對象復制(拷貝/克隆)過程7.對象的比較(一)
- 同一性 同一個東西
- 相等性 同類東西,但不是同一個
- 相似性 同內容東西,比如是版本2
Java中沒有原生提供相似性判斷邏輯的邏輯,但是有相等性判斷的約束
重寫的"equals"是相等性比較(默認是同一性比較):在Object中有一個equals(相等)方法,所有類繼承自Object類,所以都有equals方法
"=="是同一性比較:對于基本類型來說同一性就是相等性,對于引用類型來說同一性只是同一性
2022年01月06日
1.對象的比較(二)
1>comparable 接口
p1.compareTo(p2); //重寫compareTo方法// this > obj 返回 >0 // this < obj 返回 <0 // this == obj 返回 ==2>comparator 接口
comparator(p1,p2); //重寫compare方法2.Java中的字符串
String常見方法:
從前往后 indexOf() 4種:目標為String或char兩種+給定/不給定form兩種
從后往前 lastIndexOf() 4種
2022年01月09日
1.方法
String s; //判斷是否以括號內字符串為前綴boolean b = s.startsWith("字符串");boolean b = endsWith("字符串"); //判斷是否包含括號內字符串boolean b = s.contains("字符串"); //全部替換,使用一個字符(串)去替換另一個字符(串)s.replace('被替換字符', '替換字符');s.replace("被替換字符串", "替換字符串"); //全部替換s.replaceAll("被替換字符串", "替換字符串") //只替換第一個s.replaceFirst("被替換字符串", "替換字符串") //截取字符串 左閉右開substring(首下標,[尾下標]) //不輸入尾下標,默認為長度 //以括號內字符分割字符串為數組類型String[] parts = s.split("\\."); //數組通過連接符連接String v = String.join("delimiter連接符",arr) //修剪字符串兩邊的空白字符(包含空格、制表符(Nt)、回車、換行)s.trim()2.字串的不可變特性及其優化
1>不可變特性
對象一旦創建之后,無法被任何方式修改
成本:每次修改字符串,需要創建對象
收益:簡化開發難度,不會讓別人更改你給的東西
如何做到:
-
不可被繼承 類被final修飾
-
屬性被final修飾
-
防止內部的屬性對象逃逸
只能保證"指向"不指向其他對象,但不能保證指向的對象內內容不能更改,會造成屬性逃逸
2>優化
JVM使用池化(pooled)技術進行優化
邏輯上創建一個字符串對象池,這個對象池常見的術語有:哈希池
入池對象:
-
寫在代碼中的字面量字符串默認入池
-
new出來的對象默認不會入池
-
通過s.intern();強制s對象入池
如果s指向的對象已經在池里,返回池里的對象
如果不在,則將對象放入池中
3>結論
所以只比較對象的相等性,不去關心同一性的問題
3.StringBuilder 構造器
從結構上完全可以把它當成一個關于字符的順序表。
append(); toString(); //…… reverse(); replace(); substring();StringBuffer是StringBuilder的早期版本,性能極低但是線程安全的(沒有價值)。
4.異常
針對代碼中的非正常情況進行處理的
1>異常
優點:避免層層上報直到某個層級才可以處理該錯誤,發生異常就跳到能處理異常的地方
缺點:采用異常機制會帶來性能損失
- 異常情況和正常情況完全分離
- 異常走throw形式
- 正常走return形式
2>關鍵字
-
try + catch + finally
可以寫try + catch,try + finally,try + catch + finally。
誰對異常負責,誰寫try catch。
執行順序:finally一定執行
-
throw 拋出異常
throw new 異常類型的對象(引用)
-
throws 聲明風險
public void 方法(...) throws 異常1,異常2{//......要使用方法就要承擔風險異常 }這樣就可以使調用者用catch處理可能會出現的風險,不會讓它沒人負責
3>異常對象的構造方法
①無參構造方法
②允許傳入String Message
③通過一個異常構造另一個異常
飯不夠吃異常 e = ...; 物資不夠異常 exc = new 物資不夠異常(e);由于物資不夠異常,所以導致飯不夠吃異常4>Java程序中輸出內容的通道
-
標準輸出:一般用來輸出非錯誤信息
-
標準錯誤:一般用來輸出錯誤信息
目的地默認情況的情況都是控制臺,只是走兩條路,異常一般走的是緊急通道。都走正常通道先出發的一定先到達,但走兩條路不一定誰先到達。
5>異常負責
由下向上,如果沒人負責,由JVM負責,終止程序
6>編碼規范
不要吞異常(即catch異常啥也不干),可以把原有的異常作為原因寫在catch里
public void method3() throws IOException{//拋受查異常的時候必須要用throws聲明throw new IOException(); } //問題:使用method3方法會有IOException異常 //解決方法一 聲明 //public void method4() throws IOException{ //解決方法二 catch //實際中用非受查異常RuntimeException將受查異IOException常包起來 public void method4(){try{method3();}catch(IOException exc){ //解決傳染性問題throw new RuntimeException(exc); //會輸出exc信息,看到原因} }7>異常分類
-
錯誤
- 繼承自Error類的就是錯誤,也可以算作一種非受查異常
- 因為設備等其他硬性環境導致的,程序無法修復的問題,比如CPU燒了
-
受查異常(檢查異常)
-
繼承自Exception類,但不屬于RuntimeException子類的
-
程序代碼BUG,比如空指針異常,數組下標越界異常
-
使得代碼具備傳染性
使用方法就要么用catch處理要么也聲明異常列表,可以使用非受查異常把受查異常包起來,哪個類關心這個異常的時候哪個類處理它
-
-
非受查異常
- 繼承自RuntimeException類的
- 經過重試、程序自動修復解決的問題,比如內存不夠用,網絡不穩定
我們應該catch受查異常,不catch非受查異常,錯誤catch了也解決不了。由于實際的復雜性,這種規則一般不太遵守。
Java對于受查異常,強制要求:
- 一個方法如果拋出了受查異常,則必須通過throws聲明
- 一個方法如果拋出了非受查異常,可以聲明也可以不聲明
8>自定義異常 一般繼承自RuntimeException
2022年01月16日
throws 異常1,異常2{
//…要使用方法就要承擔風險異常
}
4>Java程序中輸出內容的通道
-
標準輸出:一般用來輸出非錯誤信息
-
標準錯誤:一般用來輸出錯誤信息
目的地默認情況的情況都是控制臺,只是走兩條路,異常一般走的是緊急通道。都走正常通道先出發的一定先到達,但走兩條路不一定誰先到達。
5>異常負責
由下向上,如果沒人負責,由JVM負責,終止程序
6>編碼規范
不要吞異常(即catch異常啥也不干),可以把原有的異常作為原因寫在catch里
public void method3() throws IOException{//拋受查異常的時候必須要用throws聲明throw new IOException(); } //問題:使用method3方法會有IOException異常 //解決方法一 聲明 //public void method4() throws IOException{ //解決方法二 catch //實際中用非受查異常RuntimeException將受查異IOException常包起來 public void method4(){try{method3();}catch(IOException exc){ //解決傳染性問題throw new RuntimeException(exc); //會輸出exc信息,看到原因} }7>異常分類
-
錯誤
- 繼承自Error類的就是錯誤,也可以算作一種非受查異常
- 因為設備等其他硬性環境導致的,程序無法修復的問題,比如CPU燒了
-
受查異常(檢查異常)
-
繼承自Exception類,但不屬于RuntimeException子類的
-
程序代碼BUG,比如空指針異常,數組下標越界異常
-
使得代碼具備傳染性
使用方法就要么用catch處理要么也聲明異常列表,可以使用非受查異常把受查異常包起來,哪個類關心這個異常的時候哪個類處理它
-
-
非受查異常
- 繼承自RuntimeException類的
- 經過重試、程序自動修復解決的問題,比如內存不夠用,網絡不穩定
我們應該catch受查異常,不catch非受查異常,錯誤catch了也解決不了。由于實際的復雜性,這種規則一般不太遵守。
Java對于受查異常,強制要求:
- 一個方法如果拋出了受查異常,則必須通過throws聲明
- 一個方法如果拋出了非受查異常,可以聲明也可以不聲明
8>自定義異常 一般繼承自RuntimeException
總結
以上是生活随笔為你收集整理的JavaSE总结笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何将IDEA文件提交至Gitee仓库
- 下一篇: 将用bootstrap框架的html文件