Java基礎知識
1、關鍵字
2、標識符
3、基本類型和引用類型
4、public、default、protected、private
5、static、Final、abstract
6、構造方法:
7、this 和 super
8、== 和 equals
9、字符容器(String、StringBuffer、StringBuilder)
10、File(Java 文件操作)
11、流
12、常用類(內部類、匿名類、抽象類)
13、字符問題
14、三大特性(封裝、繼承、多態)
15、繼承(extends)
16、接口(implements)
17、重寫和重載
18、數組
19、泛型
20、枚舉
21、語法基礎
22、hashcode和equals (MD5的計算是目前最廣泛的哈希算法)
23、類的加載執行、初始化
24、網絡通信(Socket)
25、調用方法的參數傳遞問題
26、public static void main(String[] args){}
27、system.out.print(): 類名.成員變量.靜態方法
// 陌生單詞:compile編譯、deprecation過時、PermGen永久代(方法區)、Heap堆內存
准備明年開始找工作,所有刷了牛客app上的900多道Java相關的筆試題,
整理了答案下面的 精華知識,以備不時之需。如有不合理之處,萬望知會。
1、關鍵字
修飾符: abstract、class、final、private、protected、public、static、7
數據類型:boolean、byte、char、double、float、int、long、short、void、9
語句組成:break、case、catch、continue、default、do、else、extends、finally、 for、if、implements、import、instanceof、interface、new、package、 return、super、switch、sychronized、this、throw、throws、try、while26
特殊含義關鍵字:assert、const、goto、enum、native、strictfp、transient、volatile、7
assert: 斷言,用於調試,多被junit代替,IDE默認不開啟。
const:預留關鍵字。
goto:預留關鍵字。
enum: 枚舉。
native: 本地方法。
strictfp: 精確浮點,可用於類、接口、方法。
transient: 免除變量序列化。
volatile: 被設計用來修飾被不同線程訪問和修改的變量。
非java關鍵字:true、false、sizeof、null、serilizable、
2、標識符
標識符是用來標識類名、變量名、方法名、類型名、數組名及文件名的有效字符序列。
1、標識符由字母、數字、下划線、美元符號組成,長度不受限制。
2、第一個字符不能為數字。
3、標識符不能是關鍵字。
4、標識符不能是true、false、null(字面常量)
3、基本類型和引用類型
Java中基本類型有四類八種,也稱為原生類、內置類。其余的都屬於引用類型
整數:(byte、short、int、long) 引用類型:(Byte、Short、Integer、Long)
浮點:(float、double) 引用類型:(Float、Double)
字符型:(char2) 引用類型:(Character)
邏輯型:(bolean1) 引用類型:(Boolean)
nume(枚舉)是基本類型
String是基本類型
一個字符常量表示一個字符或一個轉義字符,被一列ASCII單引號包裹。
數組無論是定義實例變量還是局部變量,若沒有初始化,都會被自動初始化。
char[] ch = new char[3]; //默認空格
int [] arr = new int[2]; //默認0
String[] string = new String[2]; //默認null
Byte類型引用包裝類默認為null,byte的默認值為0,byte[-128,127]
char類型存儲unicode碼,占兩個字節16位,默認值為’’,默認使用GBK編碼,可存中文漢字。UTF-8一個漢字占3個字節,GBK占兩個字節。
java中的小數類型默認值為double.
包裝類型:Integer a=1; a=2; 在方法內===>等於重新new一個a對象,
在方法外===>等於改變a的指向地址,
包裝類對象做基本操作(拆比較、計算)會拆箱,不再是引用傳遞。
引用類型一般有 數組(數組是一種對象,有行為,大小一旦確定,不能改變)、類、接口。
a = Integer.parseInt(“1024”);==>parseInt把String對象類型轉換為 int。
b= Integer.ValueOf(“1024”).intValue(); ===>ValueOf把String轉換為Integer類型,(JDK支持裝箱拆箱),intValue(); 把Integer類型轉化為int類型。
Integer i01 = 59;會調用Integer的valueOf方法,判斷是否在[-128,127]之間,返回引用或新建對象。
int i02 = 59;基本類型,存儲在棧中。
Integer i03 = Integer.valueOf(59);直接返回引用(IntegerCache中的對象引用)
Integer i04 = new Integer(59); 直接創建一個新的對象
i01 == i02; ===>Integer會拆箱成int,做值之間比較 true
i02 == i04; ====>Integer會拆箱成int,做值之間比較 true
4、public、default、protected、private
訪問權限
5、static、Final、abstract
static : 在編譯器就確定了函數和地址,不存在多態情況
靜態方法屬於類,靜態方法在對象實例創建前已經存在了,它的使用不依賴對象是否被創建,當我們通過實例來調用方法時,實際上還是把實例對象轉換成類去調用方法,這里的null沒有意義。((TestClass) null).testMethod();可以寫成TestClass t = null; t.testMethod(); null可以被強制轉換成任意類型對象。(空指針可以操作 類變量和類方法)
靜態方法不能引用非靜態變量。不能調用類的對象方法,在類方法中不能使用this、super。但可以new對象,有了對象就可以實現實例的成員變量和方法。
static修飾的為類變量和類方法,在類初始化時加載完成,可以被成員方法調用或訪問。
Final: 可以用來修飾類、變量、方法、引用。類不能被繼承,方法不能被重寫,可以繼承和重載。變量經修飾變為常量,引用不能變,在編譯期就確定,變為宏變量。
final修飾的對象引用不能變,即地址不可變,但地址中的值可變。 p.name = ”aaa”; p.name=”bbb”;但對於String(只讀類型的引用???)特殊,final String str=”aaa”; str=”bbb”; //編譯不通過,引用被改變。
final修飾方法:聲明final就是防止功能被修改。
final修飾局部變量可以在聲明時初始化,也可以在第一次使用時通過方法或表達式賦值,
final修飾的成員變量可以在類方法、聲明、初始化塊中賦值,==>沒有默認值,聲明同時賦值。
6、構造方法:
構造方法可以被public、private、Protected修飾,不能被繼承。
7、this 和 super
this: 表示某個對象,this可以出現在實例方法和構造方法中,但不可出現在類方法中。
this出現在構造方法中,代表當前對象,一般省略。
this出現在實例方法中,代表正在調用當前方法的對象,成員變量和局部變量重名時出現,多出現在set方法中,對象的成員變量。
super:子類一旦隱藏了繼承的成員變量,那么子類創建的對象就不再擁有該變量,該變量就歸super關鍵字所擁有。
在子類的構造函數中默認有super();
父類沒有無參構造時,需在子類的構造方法中顯式調用super(“xxx”);
只有在重寫了父類的方法之后,再調用父類的方法需要使用super調用。
父類靜態方法不能被子類重寫,只是被隱藏,也需要使用super調用。
8、== 和 equals
== 比較類型和值(也可以說是比較地址)
equals 底層也采用 == 做比較,但String中重寫了Object中的此方法,用於比較字符串的內容。
Object中equals的源碼,沒有重寫equals時,底層直接用“==”做判斷。而String中重寫了方法。
public boolean equals(Object obj){
return (this==obj);
}
重寫后的equals方法:
public static boolean equals(String str1, String str2) {
return str1 == null ? str2 == null : str1.equals(str2);
}
9、字符容器(String、StringBuffer、StringBuilder)
String傳遞是引用傳遞,StringBuffer是引用傳遞===>可改變內容,不可改變引用地址。
String s = new String(“xyz”); 分常量池和堆。
xyz可能存在於兩個地方,編譯期遇到”xyz”,檢測到常量池沒有xyz存在,就在常量池中創建一個xyz常量。
new String(“xyz”)會在執行時,在堆中創建一個實例。
10、File(Java 文件操作)
1)File類是對文件整體或者文件屬性操作的類,例如:創建文件,刪除文件等,文件內容用IO流操作。
2)能用文本文檔打開的都是文本文件(文本打開亂碼都不是文本文件),用特殊應用打開的都是二進制文件。
3)輸出過程到達文件或流的末尾,會拋出EOFException,正常情況異常 會被處理返回特殊值(read()會返回-1)。
11、流
字節流繼承於InputStream、OutputStream
字符流繼承 InputStreamReader/OutputStreamWriter
1)InputStreamReader的構造函數:
InputStreamReader(InputStream in): 創建一個使用默認字符集的InputStreamReader.
InputStreamReader(InputStream in,Charset cs):創建使用給定字符集的InputStreamReader
InputStreamReader(InputStream in,CharsetDecoder dec):創建使用給定解碼字符集的InputSt..
InputStreamReader(InputStream in,String charsetName):創建使用給定字符集的InputStream..
BufferedReader的構造函數:
BufferedReader(Reader in):創建使用默認大小輸入緩沖區的緩沖字符輸入流
BufferedReader(Reader in,int size):創建使用指定大小輸入緩沖區的緩沖字符輸入流
Writer的構造函數:
Protected ... Writer( ):創建一個字符流writer,其作用是同步到writer自身,
Protected...Writer(Object lock):創建一個字符流writer,作用是同步到給定的對象
管道流:管道實際上是一個大小固定的緩沖區,管程對於管道兩端的進程而言,就是一個文件,但它不是普通文件,它單獨構成一種文件系統,並且只存在內存中,類似於半雙工通信。管道的內存大小通常是內存上的一頁,它的大小並不受磁盤容量大小的限制。當管道空時,進程讀操作會堵塞,管道滿時,寫操作會堵塞。
PipedInputStream的構造函數:
PipedInputStream():創建一個尚未連接的PipedInputStream.
PipedInputStream(int pipeSize):創建尚未連接的PipedInputStream,並指定管道緩沖區的大小
PipedInputStream(PipedOutStream src):創建PipedInputStream,連接到管道輸出流src
PipedInputStream(PipedOutputStream sc,int pipeSize):創建PipedInputSt...,指定大小,連接src。
12、常用類(內部類、匿名類、抽象類)
對於局部類、方法、變量,只針對特定區域有效,訪問權限無效。
外部類的修飾符可以為 public 和 默認缺省修飾符(default)。因為外部類在包中,只有包可見和包不可見。
外部類中的內部類可以看做是外部類的成員變量。
內部類:(常規內部類、靜態內部類、局部內部類、匿名內部類)
常規內部類:沒有用static修飾且定義在外部類類體中,可直接訪問外部類成員變量、方法。
靜態內部類:與靜態內部方法相似,只能訪問外部類的static成員,可通過對象引用訪問外部類的成員變量。(實例變量、方法)
局部內部類:存在於方法體或語句塊中(包括方法、局部塊、靜態初始化塊)不能加任何修飾符,只對局部有作用。
匿名內部類:定義一個類的同時創建一個沒有名字的類稱為匿名內部類,只用一次。
靜態內部類才可以定義static方法,
內部類權限修飾符可以為public、protected(同包子類)、默認(同包)、private(同類有效),所以說一個java文件可以有多個public修飾的類。
為什么使用內部類?每個內部類都能獨立的繼承一個(接口)實現,無論是外部類是否已繼承。最大的優點就是它能夠非常好的解決多重繼承的問題。
1)內部類可以有多個實例,且每個實例有自己的狀態信息,相互獨立。
2)在單個外部類中,可以讓多個內部類以不同方式來實現同一個接口,或者繼承同一個類。
3)創建內部類實例對象不依賴外部類。
4)內部類沒有令人迷惑的” is--a ”關系,它就是一個獨立的實體。
5)內部類提供了更好的封裝,除了外部類,其他類不可訪問。
匿名類:
匿名內部類:用在任何允許存在表達式的地方,只能用一次。
局部內部類:用在任何允許出現局部變量的地方,可以在自己的定義域中多次使用。
抽象類:一般使用Protected修飾
abstract不可與final、static、private共存,因為需要被繼承,重寫方法。
抽象方法中不能有方法體,抽象類中可以沒有抽象方法。
抽象類有構造方法,可以給子類初始化,但不可實例化,(可用在匿名內部類??)
抽象類可以實現接口,也可以繼承自抽象類。
抽象類有構造方法,但不是用來實例化的,而是用來初始化的。
抽象類可以定義普通成員變量而接口不可以,但是兩者都可以定義靜態成員變量。
13、字符問題
java語言使用Unicode字符集,而ASCII是國際上使用最廣泛的字符編碼,BCD是一種數字壓縮存儲編碼Unicode(又稱統一碼、萬國碼、單一碼)是計算機學領域上的一項業界標准,包括字符集、編碼方案等,為每種語言的每個字符設定了統一並且唯一的二進制編碼,以滿足跨語言,跨平台的文本轉換。一個unicode(中英文一樣)占兩個字節(16bit)。
UTF-8、UTF-16、UTF-32都是將Unicode裝換到程序數據的編碼方案。
JVM使用UTF-16保存字符。
編碼(Unicode)就是一個編號(數字)到字符的一種映射關系,一對一的映射表。
編碼格式(UTF-8)就是序列化或存儲編碼中的那個編碼的一種”格式”。
中文漢字在java(Unicode)中占兩個字節,在utf-8中占三個字節,在gbk中占兩個字節。
標准ASCII 只使用7個bit,擴展的ASCII 使用8個bit,ASCII 中包括一些不可打印字符,0-31分配給不可打印字符,
ANSI通常使用0x00--0x7f范圍的一個字節來表示1個英文字符,即擴展的ASCII編碼。代表本地編碼格式。
簡體中文windows中,ANSI代表GBK,GB2312 是國標。
繁體中文 ANSI代表 Big5。
日文中 ANSI 代表shift_JIS。
14、三大特性(封裝、繼承、多態)
15、繼承(extends)
繼承:基類和派生類是父子關系,超類和子類也是父子關系,父類中類方法不會被繼承,屬於super關鍵字所擁有。
16、接口(implements)
接口變量用public static final修飾,為常量。方法沒有方法體,為抽象方法。
接口的方法修飾符為 public abstract,接口是通用的,不設訪問權限。
接口中沒有構造函數,
接口沒有構造函數,所以不能實例化,
17、重寫和重載
多態包括重載和重寫,
重載是方法的多態,調用方法時通過傳遞給方法的不同參數(參數個數、參數類型)來確定具體使用哪個方法。(向上轉型,編譯看左邊,決定哪些方法編譯,運行看實際類型選擇)
方法名一致,返回值類型和訪問權限沒有要求。
重載選擇執行方法時,是參考傳入參數的實際類型,而不是靜態類型(特別注意上轉型)
重寫存在於子父類中,遵循兩同兩小一大原則,
方法名、參數相同。
返回值類型、拋出異常要小。
訪問權限要大。
對於成員變量,編譯和運行都參考左邊。
對於成員函數(非靜態):編譯看左邊,運行看右邊。
對於靜態函數:編譯和運行都看左邊。
18、數組
19、泛型
泛型防止代碼編寫出錯,在編譯期,泛型會被擦除,並不會影響運行速度。
20、枚舉
枚舉是JDK1.5新增的特性,它是一種新的類型,表示特定的數據片段,類型安全,是特殊類,擁有成員變量和方法。 (寫一個根據輸入輸出星期程序)
所有的枚舉值都是類靜態常量,在初始化時會對所有的枚舉值對象進行一次初始化。
21、語法基礎
1、if(x=y)==>會出錯,發生類型強轉異常。(mismatch) 。
2、int x=1;float y=2; x/y=1.0/2.0=0.5==>發生自動轉型,byte-short-char-int-long-float-double
3、public class A extends B implements C{} ===>先繼承再實現
4、package在程序文件的第一句,且沒有注釋。
5、float f = 1.0f; f必須有。
6、int a[] = null; a[0] = 1; 拋出NullPointException。
7、<< 左移,乘以2的n次方, << 無符號左移,末尾補0, >>> 無符號左移
8、instanceOf運算符用來判斷一個變量所引用的對象的實際類型,(重點考察上轉型看實際)
9、強制轉int型,會向下取整。 int(5.7) = 5
10、包裝類相關:
兩種不同類型的引用不能進行”==”比較,例如:Integer和Double
s.equals(q);在進行equals比較之前,會對q調用Integer.valueOf;進行自動裝箱,由於IntegerCache中已經存在q,所以,直接創建了一個新的Integer實例,但值也是q,滿足條件,返回真。
包裝類也重寫equals,沒有常量池,Integer s = new Integer(q);Integer t = new Integer(q);強制在堆內存創建 q 對象實例。
11、String str1 = new String(“hello”); //正常創建對象保存在堆區
String str2 = “Hello”; //創建的字符串,保存在字符串常量區
12、當使用Integer賦值的時候,java編譯器會將其翻譯成調用ValueOf()方法,比如 Integer i = 127,對於-128到127之間的數,Java會對其進行緩存,超過這個范圍則新建一個對象。
13、求數組的長度(容量):length。
求字符串的長度:length()。
求集合的長度:size().
22、hashcode和equals (MD5的計算是目前最廣泛的哈希算法)
哈希又稱散列,通過散列算法將任意長度的輸入變成固定長度的輸出,又稱散列值,是一種壓縮映射,散列值可能相同。
1) 如果兩個對象相等,那么他們一定有相同的哈希值。
2) 如果兩個對象哈希值相等,它們不一定相等。需要用equals判斷。
hash值: 具有等冪性(對象不變,做多少次計算hash值都不變)、
對等性(equals計算兩個對象相等,而hash值一定對等)、
互異性(若兩個對象equals為false,而hash值最好也不同)
hash值的計算一般采用 多個成員變量的hash值相加,或 加權值
對象的hash值做key。
23、類的加載執行、初始化
類的加載順序:
父類靜態塊--子類靜態塊--父類初始化塊--父類構造方法--子類初始化塊--子類構造方法
靜態塊---main()---初始化構造塊-----構造方法
靜態域最先初始化,靜態域包括靜態變量和靜態方法,
new一個對象==初始化靜態塊+執行構造函數。
初始化父類靜態變量、靜態代碼塊,
初始化子類靜態變量、靜態代碼塊,
初始化父類普通成員變量、代碼塊、父類構造方法,
初始化子類普通成員變量、代碼塊、子類構造方法,
在繼承存在的情況下,類的執行:
父類靜態對象、父類靜態代碼塊
子類靜態對象、子類靜態代碼塊
父類非靜態對象、父類非靜態代碼塊、父類構造函數
子類非靜態對象、子類非靜態代碼塊、子類構造函數
Java中對字段屬性是靜態綁定(編譯出錯),方法成員是動態綁定(運行出錯)。
對象的初始化方式(實例化對象):
1)new時初始化 :調用構造函數,分配內存空間,
2)靜態工廠newInstance :
3)反射Class.forName():使用構造方法
4)clone方式:clone只是復制拷貝(深拷貝需要new,淺拷貝不需要,原來的對象的改變不反應在拷貝對象上)
5)反序列化:readObject是從文件中還原對象
24、網絡通信(Socket)
服務器端:ServerSocket server = new ServerSocket(端口號);
服務器端的常用方法:
ServerSocket(int port)、accept()、close()、getInetAddress()、getLocalPort()
客戶端: Socket soc = new Socket(ip地址,端口號);
客戶端的常用方法:
Socket(InetAddress address, int port)、 Socket(String host, int port)、close()
25、調用方法的參數傳遞問題
26、public static void main(String[] args){}
main方法中的變量也是局部變量,
27、system.out.print(): 類名.成員變量.靜態方法
system是java.lang的一個類,out是system內的一個成員變量,這個變量是java.io.PrintStream類的對象。println()是java.io.PrintStream類的方法,所以可以調用類.成員變量.println()方法。
// 陌生單詞:compile編譯、deprecation過時、PermGen永久代(方法區)、Heap堆內存