Java基礎語法,常用知識複習
1.開發環境搭建
1.1JDK、JRE、JVM、的關係
JDK = JRE + 開發工具集(例如javac編譯工具集等)
JRE = JVM + Java SE 標準類庫
2.基本語法
2.1.java關鍵字的使用
2.2保留字
goto const
2.3變數
2.3.1變數的分類
按數據類型分類
按聲明的位置分類
1. 整型:byte(1位元組=8bit) \ short(2位元組) \ int(4位元組) \ long(8位元組)
① byte範圍:-128 ~ 127
② 聲明long型變數,必須以"l"或"L"結尾
③ 通常,定義整型變數時,使用int型。
④整型的常量,默認類型是:int型
2. 浮點型:float(4位元組) \ double(8位元組)
① 浮點型,表示帶小數點的數值
② float表示數值的範圍比long還大
③ 定義float類型變數時,變數要以"f"或"F"結尾
④ 通常,定義浮點型變數時,使用double型。
⑤ 浮點型的常量,默認類型為:double
3. 字元型:char (1字元=2位元組)
① 定義char型變數,通常使用一對'',內部只能寫一個字元
② 表示方式:1.聲明一個字元 2.轉義字元 3.直接使用 Unicode 值來表示字元型常量
4.布爾型:boolean
① 只能取兩個值之一:true 、 false
② 常常在條件判斷、循環結構中使用
2.3.2基本數據類型變數間運算規則
1.自動類型轉換(只涉及7種基本數據類型)
結論:當容量小的數據類型的變數與容量大的數據類型的變數做運算時,結果自動提升為容量大的數據類型。
byte 、char 、short --> int --> long --> float --> double
特別的:當byte、char、short三種類型的變數做運算時,結果為int型
說明:此時的容量大小指的是,表示數的範圍的大和小。比如:float容量要大於long的容量
char a = 'a';
char b = 'b';
//char c = a + b;編譯錯誤
int c = a + b;
2.強制類型轉換(只涉及7種基本數據類型):自動類型提升運算的逆運算。
需要使用強轉符:()
注意點:強制類型轉換,可能導致精度損失。
3.String可以和8種基本數據類型變數做運算,且運算只能是連接運算:+
2.4進位(個人覺得需要掌握)
二進位(binary)0,1 滿2進一 以0b或0B開頭
十進位(decimal)0-9 滿10進一
八進位(octal)0-7 滿8進一 以數字0開頭表示
十六進位(hex)0-9 及A-F 滿16進一 以0x 或0X開頭表示 此處A-F不區分大小寫
1.二進位的說明
1.1 電腦底層的存儲方式:所有數字在電腦底層都以二進位形式存在。
1.2 二進位數據的存儲方式:所有的數值,不管正負,底層都以補碼的方式存儲。
1.3 原碼、反碼、補碼的說明:
正數:原碼,反碼,補碼相同
負數:
原碼:正數的源碼的符號位取反
反碼:符號位不變,其餘按位取反
補碼:反碼+1
1.4進位轉換
十進位 -> 二進位 除2取余的逆
二進位轉八進位 三位合成一位
二進位轉十六進位 四位合成一位
2.5運算符
1.算術運算符: + - + - * / % (前)++ (後)++ (前)-- (後)-- +
short s1 = 10;
s1 = s1 + 2;//編譯失敗
s1 += 2;//不會改變變數本身數據類型
s1 ++;//不會改變變數本身數據類型
2.賦值運算符:= += -= *= /= %=
3.比較運算符(關係運算符): == != > < >= <= instanceof
4.邏輯運算符:& && | || ! ^
^ 邏輯異或 true ^ false == true false ^ false == false true ^ true == false
5.位運算符:<< >> >>> & | ^ ~
【面試題】 你能否寫出最高效的2 * 8的實現方式?
答案:2 << 3 或 8 << 1
【特別說明的】
1. 位運算符操作的都是整型的數據
2. << :在一定範圍內,每向左移1位,相當於 * 2 (補0)
>> :在一定範圍內,每向右移1位,相當於 / 2 (正數補0負數補1)
3.>>> 無符號右移,無符號始終補0
6.三元運算符:(條件表達式)? 表達式1 : 表達式2
//交換兩個變數的值。
//方式1
int a = 1;
int b = 3;
a = a + b;
b = a - b;
a = a - b;
//方式2
a = a ^ b;// 00000001 ^ 00000011 = 00000010
b = a ^ b;// 00000010 ^ 00000011 = 00000001
a = a ^ b;// 00000010 ^ 00000001 = 00000011
3.數組
1.數組是序排列的
2.數組屬於引用數據類型的變數。數組的元素,既可以是基本數據類型,也可以是引用數據類型
3.創建數組對象會在記憶體中開闢一整塊連續的空間
4.數組的長度一旦確定,就不能修改。
數組的演算法
4.面向對象(封裝、繼承、多態)
4.1屬性
1.相同點:
定義變數的格式:數據類型 變數名 = 變數值
先聲明,後使用
變數都其對應的作用域.
2.不同點:
在類中聲明的位置的不同
屬性:直接定義在類的一對{}內
局部變數:聲明在方法內、方法形參、程式碼塊內、構造器形參、構造器內部的變數
3.默認初始化值的情況:
屬性:類的屬性,根據其類型,都默認初始化值。
整型(byte、short、int、long:0)
浮點型(float、double:0.0)
字元型(char:0 (或'\u0000'))
布爾型(boolean:false)
引用數據類型(類、數組、介面:null)
局部變數:沒默認初始化值。
意味著,我們在調用局部變數之前,一定要顯式賦值。
特別地:形參在調用時,我們賦值即可。
4.在記憶體中載入的位置:
屬性:載入到堆空間中 (非static)
局部變數:載入到棧空間
4.2方法(重寫、重載)
1.方法的重載的概念
定義:在同一個類中,允許存在一個以上的同名方法,只要它們的參數個數或者參數類型不同即可。
總結:"兩同一不同":
同一個類、相同方法名
參數列表不同:參數個數不同,參數類型不同,參數類型的順序不同
2.方法的重寫
①yi什麼是方法的重寫(override 或 overwrite)?
子類繼承父類以後,可以對父類中同名同參數的方法,進行覆蓋操作.
②應用:
重寫以後,當創建子類對象以後,通過子類對象調用子父類中的同名同參數的方法時,實際執行的是子類重寫父類的方法。
③重寫的規則:
4.重寫的規則:
方法的聲明: 許可權修飾符 返回值類型 方法名(形參列表) throws 異常的類型{
//方法體
}
約定俗稱:子類中的叫重寫的方法,父類中的叫被重寫的方法
① 子類重寫的方法的方法名和形參列表與父類被重寫的方法的方法名和形參列表相同
子類重寫的方法的許可權修飾符不小於父類被重寫的方法的許可權修飾符
>特殊情況:子類不能重寫父類中聲明為private許可權的方法
③ 返回值類型:
>父類被重寫的方法的返回值類型是void,則子類重寫的方法的返回值類型只能是void
>父類被重寫的方法的返回值類型是A類型,則子類重寫的方法的返回值類型可以是A類或A類的子類
>父類被重寫的方法的返回值類型是基本數據類型(比如:double),則子類重寫的方法的返回值類型必須是相同的基本數據類型(必須也是double)
④ 子類重寫的方法拋出的異常類型不大於父類被重寫的方法拋出的異常類型(具體放到異常處理時候講)
**********************************************************************
子類和父類中的同名同參數的方法要麼都聲明為非static的(考慮重寫,要麼都聲明為static的(不是重寫)。
一個為static,另一個為非static的話,編譯會不通過。
3.可變個數和形參
public void show(String ... strs){}
public void show(String[] strs){}
這個兩個方法不能同時存在
可變個數形參在方法的形參中,必須聲明在末尾
可變個數形參在方法的形參中,最多只能聲明一個可變形參。
4.值傳遞相關面試題
main(){
Hello hello = new Hello();
say(hello);
sout(hello);//0x2345
}
say(Hello hello){
hello = null;
sout(hello);//null
}
5.遞歸
4.3封裝
1.為什麼要引入封裝性?
我們程式設計追求「高內聚,低耦合」。
高內聚 :類的內部數據操作細節自己完成,不允許外部干涉;
低耦合 :僅對外暴露少量的方法用於使用。
隱藏對象內部的複雜性,只對外公開簡單的介面。便於外界調用,從而提高系統的可擴展性、可維護性。通俗的說,把該隱藏的隱藏起來,該暴露的暴露出來。這就是封裝性的設計思想。
2.封裝性思想具體的程式碼體現:
體現一:將類的屬性xxx私化(private),同時,提供公共的(public)方法來獲取(getXxx)和設置(setXxx)此屬性的值
體現二:不對外暴露的私有的方法
體現三:單例模式(將構造器私有化)
體現四:如果不希望類在包外被調用,可以將類設置為預設的。
4.4繼承
1.為什麼要有類的繼承性?(繼承性的好處)class A extends B{}
* ① 減少了程式碼的冗餘,提高了程式碼的復用性
* ② 便於功能的擴展
* ③ 為之後多態性的使用,提供了前提
2.子類繼承父類以後有哪些不同?
一旦子類A繼承父類B以後,子類A中就獲取了父類B中聲明的所有的屬性和方法
特別的,父類中聲明為private的屬性或方法,子類繼承父類以後,仍然認為獲取了父類中私的結構。只因為封裝性的影響,使得子類不能直接調用父類的結構而已。
子類繼承父類以後,還可以聲明自己特有的屬性或方法:實現功能的拓展。
3.Java中繼承性的說明
一個類可以被多個子類繼承。
Java中類的單繼承性:一個類只能有一個父類
子父類是相對的概念。
子類直接繼承的父類,稱為:直接父類。間接繼承的父類稱為:間接父類
子類繼承父類以後,就獲取了直接父類以及所間接父類中聲明的屬性和方法
4.java.lang.Object類的理解
如果我們沒顯式的聲明一個類的父類的話,則此類繼承於java.lang.Object類
所的java類(除java.lang.Object類之外都直接或間接的繼承於java.lang.Object類
意味著,所的java類具有java.lang.Object類聲明的功能。
4.5多態
1.多態性的理解:可以理解為一個事物的多種形態。
2.何為多態性:
對象的多態性:父類的引用指向子類的對象(或子類的對象賦給父類的引用)
舉例:
Person p = new Man();
Object obj = new Date();
3.多態性的使用:虛擬方法調用
> 有了對象的多態性以後,我們在編譯期,只能調用父類中聲明的方法,但在運行期,我們實際執行的是子類重寫父類的方法。
> 總結:編譯,看左邊;運行,看右邊。
4.多態性的使用前提:
① 類的繼承關係 ② 方法的重寫
5.多態性的應用舉例:
舉例:
public void func(Animal animal){//Animal animal = new Dog();
animal.eat();
animal.shout();
}
6.多態性使用的注意點:
對象的多態性,只適用於方法,不適用於屬性(編譯和運行都看左邊)
public static void main(String[] args) {
Animal animal = new Dog();
System.out.println(animal.name);//動物
System.out.println(animal.getName());//狗
}
class Animal{
String name = "動物";
int age;
public String getName(){
return this.name;
}
}
class Dog extends Animal{
String name = "狗";
int age = 12;
public String getName(){
return this.name;
}
}
************************************************************
7.關於向上轉型與向下轉型:
7.1 向上轉型:多態
7.2 向下轉型:
7.2.1 為什麼使用向下轉型:
有了對象的多態性以後,記憶體中實際上是載入了子類特有的屬性和方法的,但是由於變數聲明為父類類型,導致編譯時,只能調用父類中聲明的屬性和方法。
子類特有的屬性和方法不能調用。如何才能調用子類特的屬性和方法?使用向下轉型。
7.2.2 如何實現向下轉型:
使用強制類型轉換符:()
7.2.3 使用時的注意點:
① 使用強轉時,可能出現ClassCastException的異常。
② 為了避免在向下轉型時出現ClassCastException的異常,我們在向下轉型之前,先進行instanceof的判斷,一旦返回true,就進行向下轉型。如果返回false,不進行向下轉型。
7.2.4 instanceof的使用:
① a instanceof A:判斷對象a是否是類A的實例。如果是,返回true;如果不是,返回false。
② 如果 a instanceof A返回true,則 a instanceof B也返回true.其中,類B是類A的父類。
③ 要求a所屬的類與類A必須是子類和父類的關係,否則編譯錯誤。
4.6關鍵字
4.6.1 this
1.可以調用的結構:屬性、方法;構造器
2.this調用屬性、方法:
this可以理解為:當前對象或當前正在創建的對象
在類的方法中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前對象屬性或方法。但是,
通常情況下,我們都擇省略"this."。特殊情況下,如果方法的形參和類的屬性同名時,我們必須顯式
的使用"this.變數"的方式,表明此變數是屬性,而非形參。
在類的構造器中,我們可以使用"this.屬性"或"this.方法"的方式,調用當前正在創建的對象屬性或方法。
但是,通常情況下,我們都擇省略"this."。特殊情況下,如果構造器的形參和類的屬性同名時,我們必須顯式的
使用"this.變數"的方式,表明此變數是屬性,而非形參。
3.this調用構造器:
① 我們在類的構造器中,可以顯式的使用"this(形參列表)"方式,調用本類中指定的其他構造器
② 構造器中不能通過"this(形參列表)"方式調用自己
③ 如果一個類中有n個構造器,則最多有 n - 1構造器中使用了"this(形參列表)"
④ 規定:"this(形參列表)"必須聲明在當前構造器的首行
⑤ 構造器內部,最多只能聲明一個"this(形參列表)",用來調用其他的構造器
4.6.1 super
1.super 關鍵字可以理解為:父類的
2.可以用來調用的結構:屬性、方法、構造器
3.super調用屬性、方法:
我們可以在子類的方法或構造器中。通過使用"super.屬性"或"super.方法"的方式,顯式的調用父類中聲明的屬性或方法。
但是,通常情況下,我們習慣省略"super."
特殊情況:當子類和父類中定義了同名的屬性時,我們要想在子類中調用父類中聲明的屬性,則必須顯式的使用"super.屬性"的方式,
表明調用的是父類中聲明的屬性。
特殊情況:當子類重寫了父類中的方法以後,我們想在子類的方法中調用父類中被重寫的方法時,則必須顯式的使用"super.方法"的方式,
表明調用的是父類中被重寫的方法。
4.super調用構造器:
我們可以在子類的構造器中顯式的使用"super(形參列表)"的方式,調用父類中聲明的指定的構造器
"super(形參列表)"的使用,必須聲明在子類構造器的首行!
我們在類的構造器中,針對於"this(形參列表)"或"super(形參列表)"只能二一,不能同時出現
在構造器的首行,沒顯式的聲明"this(形參列表)"或"super(形參列表)",則默認調用的是父類中空參的構造器:super()
在類的多個構造器中,至少一個類的構造器中使用了"super(形參列表)",調用父類中的構造器
4.6.2 static
1.可以用來修飾的結構:主要用來修飾類的內部結構
屬性、方法、程式碼塊、內部類
2.static修飾屬性:靜態變數(或類變數)
2.1 屬性,是否使用static修飾,又分為:靜態屬性 vs 非靜態屬性(實例變數)
實例變數:我們創建了類的多個對象,每個對象都獨立的擁一套類中的非靜態屬性。當修改其中一個對象中的非靜態屬性時,不會導致其他對象中同樣的屬性值的修改。
靜態變數:我們創建了類的多個對象,多個對象共享同一個靜態變數。當通過某一個對象修改靜態變數時,會導致其他對象調用此靜態變數時,是修改過了的。
2.2 static修飾屬性的其他說明:
① 靜態變數隨著類的載入而載入。可以通過"類.靜態變數"的方式進行調用
② 靜態變數的載入要早於對象的創建。
③ 由於類只會載入一次,則靜態變數在記憶體中也只會存在一份:存在方法區的靜態域中。
④ 類變數 實例變數(是否可以調用)
類 yes no
對象(引用) yes yes
2.3 靜態屬性舉例:System.out; Math.PI;