java的入門基本知識

/** */ 文檔註釋,放在類,模塊前面,介紹各部分作用,相當於字典。

java的異常處理機制異常處理

標識符【自己定義的名字,如包名,類名,方法名,變量名等】:由字母,數字,_,$組成,且不能以數字開頭,不能爲關鍵字。
駝峯命名—>從第二個單詞開始,首字母大寫。
除類名第一個單詞首字母大寫,其他命名規範都是從第二個單詞開始首字母大寫。

每一個變量由於數據類型不同,所佔的內存大小不同---->程序運行起來所佔的系統的內存不同。

System.currentTimeMillis();
返回毫秒,與系統當前時間有關。

Java語言類型:

1.基本數據類型:
數值類型:
		整數類型:
				byte  佔1字節:-128~127
				short 佔2字節:-32768~32767
				int   佔4字節:-21億~21億
				long  佔8字節: -9..(19位)~9..(19位)
		浮點類型:
				float 佔4字節
				double佔8字節
		字符類型:
				char  佔2字節
boolean類型:    佔1位,true或false
2.引用數據類型:
類,接口,數組

當直接寫一個整數時,java默認是int類型,若想讓這個整數原本表示的類型就是long類型----->在整數後緊跟一個l或L(小寫L或大寫L)

當直接寫一個小數時,java默認是double類型,若想讓這個小數原本表示的類型就是float類型----->在小數後緊跟一個f或F(小寫f或大寫F)

當直接寫一個整數時,byte和short可以自動轉換,如:byte a = 100; short b = 120;(當默認的int類型的值在byte和short的範圍內時),double和float沒有辦法自動轉換。如【float c = 12.3;】是無法自動轉換成功的。 下處爲截圖:在這裏插入圖片描述

數據類型轉換:【在將數據類型 全部顯示定義 後,與上述情況不同】
小類型到大類型的自動轉換:byte–>short,char—>int—>long–>float—>double
(雖然float佔4字節,long佔8字節,但float表示的數的範圍大於long表示的數的範圍,,因爲浮點型的數據一部分位數表示有效位數,一部分位數表示次方)
浮點型強制轉整型,小數部分捨去。

浮點類型存儲與運行的不精確性:
浮點數運算:
在這裏插入圖片描述
實際運行結果:
在這裏插入圖片描述
原因:double和float的類型的數據在java中本身就是非精確存儲的,以float來說,共32位,前一部分用來存儲數據,後一部分用來存儲次方,採用科學記數法存儲,才導致其前一部分的數據部分的存儲本就不精確。

++與–運算符在數字前後的區別:
自增自減運算符在後:先進行該算式的運算(輸出),再將數字自增或自減。
自增自減運算符在前:先將數字自增或自減(輸出),再進行該算式的運算。
例:

int a = 9; int b = 5;
int res1 = a++;//<==>res1 = a; a++;
int res2 = ++b;//<==>b++; res2 = b;
System.out.println(res1);//   輸出9
System.out.println(res2);//   輸出6

自增與自減元素符的優先級先與賦值符號

int a = 5;
a = ++a + a++; 
System.out.println(a); /* --->輸出 12 ;
          ++a ==6,6+6=12(此時還沒有使用賦值符號,12此時暫存在內存,還未賦值),
          a++後 a=7(此時使用了自增符號),a = 12(將算式所得的結果 12 賦值給變量 a,
          此時使用了賦值符號,,a = 12 的賦值的時間節點晚於 a = 7 的賦值的時間節點),
          ,所以結果爲 12。*/

連等運算(可以但不推薦):
例:

int x,y,z;
x=y=z=6;//<==> z = 6; y = z = 6; x = y = 6;

邏輯運算符:
^ 異或:boolean兩邊不相同—>true,兩邊相同—>false
&& 短路與:
|| 短路或: —>短路與不短路(& 與 |)的區別:
當boolean結果可以通過第一個操作數進行判斷時,短路運算符後的操作數不進行運算。
例:

int b = 10;
第二個操作數爲 (++b > 8) 
則若被第一個操作數短路,println(b);--->所得仍爲 10 。

說明:&與| :運算符兩邊是boolean爲邏輯運算符,兩邊爲整數 則爲 位運算符。

位運算符:
前景知識:
計算機存儲數據時,存儲正數—>正數的原碼,,存儲負數—>負數的補碼。。
正數:原碼,反碼,補碼相同
負數:原碼(符號位爲1)
反碼(符號位不變,其餘位取反)
補碼(反碼+1)
位運算符是對計算機存儲的這些數據進行的運算,所以要先了解計算機是如何存儲這些數據的。
由此—>:
以 & 按位與:對應位都爲1才爲1
爲例:
&兩個二進制形式的整數所得的結果:
爲正數—>則說明是以原碼方式存儲,結果本來就爲正數,所得即爲結果,,爲負數—>則說明是以補碼方式進行存儲,結果本來應爲負數,通過補碼-1,再除符號位其餘取反得到原碼—>即得到結果】

| 按位或 :對應位有一個1,就爲1
按位取反 (單目運算): 1變0,0變1
^ 按位異或 :對應位 不一樣 則爲 1.
<< 左移:(高位拋棄,低位補0)
>> 右移 :(高位按照符號位補齊,低位拋棄)
【原來的符號位是0或1,高位就都補成0或1】
>>> 無符號右移 :(忽略符號位,高位補0,低位拋棄)
【沒有無符號左移,因爲左移時符號位會自動被頂替上,所以不用考慮符號位的符號】
【位移運算 如 9>>3,表示將以原碼形式存儲在計算機中的9右移3位】

三目運算符:
規則:布爾表達式?表達式1:表達式2
如:

	System.out.println(8>2?"8大於2":"8小於2");

語句塊 : 以 { 開始,以 } 結束的成塊代碼,都被稱爲語句塊。
如:在一個方法(函數)內部也可以使用{ },
在一個方法體內,{}外與{}內的語句仍爲順序執行。
語句塊可以訪問外面定義的變量,外面的語句無法訪問語句塊內部定義的變量—>
在一個方法中{}內定義 int a = 1; {} 外無法訪問該變量。

if:
特殊用法:

if(5 > 4);  //if條件後緊跟 ; ,空的if方法體,即滿足條件後,不執行任何語句。

switch:
switch(x)
{
case x: … ;
break;
default:
… ;} //–>【switch的判斷是否相等的條件可以是:整數,字符,枚舉,字符串

接收用戶鍵盤的輸入:

import  java.util.Scanner;

Scanner Scan = new Scanner(System.in);
int  x = Scan.nextInt();
String s  = Scan.next();

字符串:
字符串無法被修改 是指–>字符串的值無法被修改,但字符串對象可以引用別的字符串
內存區域:棧,堆,方法區(其中還包含 運行常量區)
下圖詳解:
在這裏插入圖片描述
棧中存放的基本數據類型(包含該變量及該變量對應的值,如a–>12),引用類型的變量和對應的地址(如 s–>045),

程序通過變量中存儲的地址 找到該變量引用的值(位於大區域中的值s1),如圖若給引用類型變量s再賦值時,會在大區域產生一個新的值,同時變量s所存儲的地址會改變成048進而指向新的值s2。

------------------------------------------------------------------------------

查找子字符串的位置:
s.indexOf(int c);// —>指傳遞一個char,因爲傳遞char類型會自動轉換成int類型,
//傳遞int類型也會根據其對應的char字符在字符串s中進行查找。
s.lastIndexOf(String str); 等近似方法。。

深層理解String引用類型的"==“與”.equals()"比較。
如:

String Str1 = "創建的字符串變量";
String Str2 ="創建的字符串變量";
String Str3 = new String("創建的字符串變量");
System.out.println(Str1 == Str2); // 輸出 true
System.out.println(Str1 == Str3); // 輸出 false

原因如下詳解:
在這裏插入圖片描述
字符串常量(“創建的字符串常量”) 在 運行常量區 佔據一定的內存空間,變量Str1,Str2及其其中存儲的內存地址(054) 在 棧 中存儲,其中的內存地址 指向 運行常量區中 存儲的常量,【當 賦值Str2 語句的語句執行時,程序查詢發現 運行常量區 中已存在相同的常量,於是不再生成新的常量 】,【賦值Str3時,由於new 了一個 新的 String 對象,new 一個對象時會將該 新的對象放置在堆中 】,新的Str3變量及其存儲的067地址 位於 棧 中,067地址指向 堆 中的對象,新的對象 中存儲的地址(054) 指向Str3 對應的常量。

String屬於引用類型,引用類型的變量間的 “==”—>比較變量中存儲的地址(引用)是否相等,引用類型的變量間的".equals()"—>比較變量中存儲的常量是否相等。

擴充:如 int[] array = new int[50];
則引用類型的array會在棧中存儲,new出的50個內存地址成塊的存儲在堆中,變量array中存儲的引用 指向 堆中成塊 內存地址。


String s1 =new String("11");
String s2 = new String("11");
System.out.println(s1 == s2); //false
System.out.println(s1.equals(s2)); //true

可見每new一次(即使該對象存儲的值相同),都會在堆中創建一個對象,該對象的地址存儲在棧中的是s1和s2中,==比較這兩個不同的引用。
-------------------------------------------------------------------------------

上述,基本類型和引用類型
基本類型存儲實際數據,引用類型存儲引用(內存地址)。
基本類型變量聲明出來不管是否賦值,都在棧中分配內存,引用類型同理,且引用的初始化會在堆或方法區中分配內存。
關於棧:所有 局部變量(在方法中創建的變量都是局部變量) 都存放在棧裏面。
引用類型:引用類型還未初始化時,將其 引用 賦爲null 是個良好的編程習慣,即使是隻賦爲null,即可在println中使用。(如: int [] array = null;)

字符串排序:
Str1.compareTo(Str2); // 兩個字符串,逐個字符進行比較,遇到相同的字符跳過,直到遇到不同的字符,返回字符(s1 - s2)的值。
若某一字符串是另一字符串的前一部分的子串,則返回Str1.length() - Str2.length() 所得的值。 若完全相等,則返回0;

s.split(String str);—>字符串劃分只能使用字符串作爲參數
當用於劃分的字符串位於原字符串的首部或尾部時:
String str =“sttrsttrs”;
String[] strs = str.split(“s”);
【strs.length == 3,最後劃分出的3部分依次是 “”,“ttr”,“ttr”】首劃分,尾不劃分

探索轉義字符"":
例:

String s = "siki.com";
String[] strs  = s.split("\\.");

// 欲使用 “.”劃分該字符串,則需要使用“\.",原因如下
“.”在java中屬於特殊字符!!,“.”其在java中實際存儲時是以“\.”來進行存儲的【即實際上在Java中 “.” == “\.”】,所以要想使用“.”來進行劃分,需將特殊字符 “.“進行轉義來使其真正表示”.”。
進行轉義就要使用轉義字符"\",但若只使用一個"\",因爲"\“是轉義字符【即”\“是一個特殊字符】,所以當想使用”\“將特殊字符進行轉義時,需再使用一個”\“來將”\“進行轉義【即想使用”\“將特殊字符進行轉義時,兩個”\\“才表示一個”\"】。

規律:傳遞參數時,“n,s等"都不是特殊字符,而”.“是特殊字符,所以要想傳遞”.",需在前面加2個"\"。而當想要傳遞"\n,\s等"爲參數時,由於\n,\s爲特殊字符,再加上該特殊字符中包含一個"\",所以需在其前面加上3個"\",【才能將特殊字符"\n"轉義爲普通字符串"\n"】。
設置字符串時,“n,s,. 等"都是普通的字符,不需要轉義。
當要在字符串中表示”\n,\s,\.“時,只需要在其前面加上1個”\"【將特殊字符"\n"轉義爲普通的"\n"字符串,將轉義字符"\“轉義爲普通字符”\"】即可。----->【傳遞參數時,由於"\\.“等價於”.",要想傳遞"\.",—>就已經相當於字符串中普通字符".“表示”\.“了,即再在其前面加2個”\",但此時也表示分割符是普通字符串"\n,\s",其可以分割設置的字符串中的"\n","\\n","\.","\\s","\s"】。

-------------------

設置字符串時:

	輸入的    n,s,.     <====>  n,s,.  
	輸入的 \\n,\\s,\\.  <====>  \n,\s,\.

傳遞參數時:

    輸入的 n,s       <====> n,s
    輸入的 \\.       <====> .
    輸入的 \\\\n,\\\\s <====> \n,\s
    輸入的 \\\\.     <====> \.,\n,\s等
    				-->其可以分割設置的字符串中的"\\n","\n","\\s","\s","\\."
    輸入的 \\\\\\.   <====> \.

Java的API含義:
API <==>應用接口

隨機數
除了java默認導入的包自帶的Math.random()來生成隨機數之外,

import java.util.Random;
Random r = new Random();
r.nextInt(10);

random.nextInt(int x);
如:其中若參數爲10,則隨機生成0~9之間的整數(左右包含),即隨機生成0至(x - 1)之間的整數。

數組:
數組的3種創建:
int[] array = new int[50];
int[] array = new int[]{1,2,3,4,5};
int[] array = {1,2,3,4,5};

數組間引用的賦予

int[] a = {1,2,3,4,5};
int[] b = null; //此時b的引用是null,null的指向是空指向
b = a;  
System.out.println(a[0]+" "+b[0]);
b[0] = 800;
System.out.println(a[0]+" "+b[0]);

運行結果:
在這裏插入圖片描述
原因:
在這裏插入圖片描述
代碼

b = a;

是將a中存儲的引用(指向的內存地址)賦給b,使b中原來存儲的null變成 a中的引用。
而代碼

b[0] = 800;

是程序根據 b 的引用改變 其 指向的內存地址中的數據,而a指向的也是同一個內存地址中的數據,所以即a[0]也被更改。

關於深究上述程序中沒有使用new的{1,2,3,4,5}是否位於運行常量區:
在這裏插入圖片描述
如果{1,2,3,4,5}位於運行常量區,則b變量在賦值引用時,發現指向的數據已經存在於運行常量區,則b中的引用會與a中的引用相同—>都是運行常量區中該數據的內存地址。
而實際運行結果是:
在這裏插入圖片描述
結果中:a與b中存儲的引用(指向的內存地址)不相同—>說明即使是沒有使用new而創建的{1,2,3,4,5}是位於堆中的,{1,2,3,4,5}相當於一個新的對象。
(此點與String的new與不new不同,也打破了只有new纔會在堆中創建的錯誤想法)

使用指定值部分填充數組:

import java.util.Arrays;

在這裏插入圖片描述
支持多種數據類型的數組的填充。

**二維數組:**在使用中理解成是一維數組的一維數組
3種聲明方式:

//第1種,固定數組規模
int[][] arrays = new int[10][50];
//第2種,根據括號中一維數組的長度自動形成,聲明形式固定
int[][] arrays = {{1,2,3},{0,1,2,3,4},{1}};
//第3種,爲 新開闢內存的一維數組(如下剛開始是10個null),
//隨後爲各個一維變量賦予引用,,聲明形式固定
int[][] arrays = new int[10][];
arrays[0] = new int[]{1,2,3};
arrays[1] = new int[]{0,1,2,3,4}

方法調用對數據產生的影響:
方法調用時,會在棧中佔據一定的內存空間【理解爲:調用方法時,方法有自己的一個棧,這個棧用來存儲方法調用的時候它所需要的一些內存的】。方法調用過後,其所佔用的內存空間會被刪除掉。
例:

public static void main(String[] args){
//傳遞基本類型變量,傳遞的是值,方法對[棧中方法的空間中的變量]的值更改--->
//      對原變量不產生任何影響,輸出 10
int a = 10;
methodA(a);
System.out.println(a);

//傳遞引用類型變量,傳遞的是引用,方法通過引用對值進行更改--->
//      使原變量對應的值改變,輸出100
int[] b = {10};
methodB(b);
System.out.println(b[0]);

//傳遞引用類型的變量,傳遞的是引用,對[棧中方法的空間中的變量]賦予新的引用--->
//       對原變量不產生任何影響,輸出10
int[] c = {10};
methodC(c);
System.out.println(c[0]);
}

public static void methodA(int a){
a = 100;
}
public static void methodB(int[] a){
a[0] = 100;
}
public static void methodC(int[] a){
a = new int[10];
}

methodA()的執行:
在這裏插入圖片描述
methodB()的執行:
在這裏插入圖片描述
methodC()的執行:
在這裏插入圖片描述

方法重載:
方法名一樣,參數不一樣–>即稱爲方法重載

成員變量:
類中定義,【因爲是成員變量,所以只在堆中佔用內存!!
成員變量定義時並不佔用內存,,new時纔開始在堆中佔用內存,
【堆中new出來的對象什麼時候被 銷燬(標記爲未使用)
當沒有任何變量引用該對象時】,
有默認值,不必須初始化,

局部變量:
方法中定義,
方法開始調用時,開始在棧中【若是引用類型,也會在堆中佔用一些內存空間】佔用內存,方法調用結束(方法返回)時,被銷燬
無默認值,必須初始化

理解爲,每個方法運行時都會在棧中佔用其獨有的一塊內存,其中的局部變量在其專有的空間中。

垃圾回收機制:
java虛擬機不斷檢測 堆中的對象,一旦其不被任何 其他對象(包括棧中的對象(變量) 和 堆中的其他對象) 所引用(指向),就會被銷燬。

private:
成員(屬性或方法)被設置爲private後將只能在該類內部使用。

構造方法:
只有當new對象的類中沒有任何的構造方法時,纔會爲其提供默認的無參構造方法。
當new對象的類中存在任何構造方法,都不會爲其提供默認的無參構造方法。

封裝:
設置set,get方法。

static關鍵字(靜態修飾符):
1.在內存中的靜態變量的表示形式(其中country是Person類中的成員變量):
在這裏插入圖片描述
修飾成員變量表示靜態變量,靜態變量是所有對象公用的,同一個類的同一個靜態變量只佔據一份內存。
2.在內存中的靜態成員方法的表示形式(其中show是Person類中的成員方法):
在這裏插入圖片描述
static修飾成員方法表示靜態方法,靜態方法裏面只能直接訪問靜態變量。
因爲如果在靜態方法中直接訪問某一變量,則不知道訪問的是哪個對象的成員變量?所以在靜態方法中只能直接訪問該類的靜態變量(不帶變量名前綴,且該類只有一個該變量不會引起歧義)。。
但在靜態方法中可以訪問該類的非靜態變量,只需爲某非靜態變量加前綴實例名即可。

static作用:工具類的創建—>工具類中含有大量static方法,因此使用時不需要先new對象,可以直接用類名作前綴,使用時方便快捷,(如Arrays類和Math類)。。將工具類的構造方法private,可以防止使用其中的方法時使用複雜的方式(先實例化再使用方法)。

使用String[] args:
在運行java程序時,可以在後面跟上參數(空格隔開),參數直接傳遞到args數組中。
在這裏插入圖片描述
在這裏插入圖片描述
幫助文檔的生成:
使用/** */文檔註釋爲類和方法進行文檔註釋。
在這裏插入圖片描述
使用【javadoc -d 註釋文檔名 用於生成註釋文檔的java文件】
生成註釋文檔。。
在這裏插入圖片描述
靜態代碼塊:
靜態代碼塊 static{} 在類加載的時候執行,如類中(不是在方法中)包含一個靜態代碼塊。
在這裏插入圖片描述

繼承:
1.當多個類含有相同的屬性和行爲時常考慮使用繼承 extends (單繼承)
2.當子類中的變量名與父類重名時,採取就近原則選取變量
3.當沒有顯式的調用(使用super調用)父類裏的構造方法時,默認會調用父類裏的無參構造方法,對父類中的屬性進行初始化。顯式調用時,super()必須是子類構造函數中的第一條語句,來調用父類的構造方法。【即通過子類的構造方法構造子類對象時,一定會調用父類裏的構造方法】
4.對this();的調用和對super();的調用必須是構造器中的第一個語句。
5.方法重寫(方法覆蓋):
子類中的方法重寫不能降低父類中被重寫方法的訪問權限!
6.重寫與重載的不同:
重寫:子類與父類之間,,方法名,參數,返回值 都相同。
重載:同一個類中,,方法名相同,參數不相同,返回值不要求。
7.final
final類:不能被繼承
final方法:不能被重寫
final變量:時恆定的自定義常量。

包 package:
定義包名:package xx.xx.xx
在DOS上對帶包名的類進行編譯和執行:

編譯:  javac -d . 類名.java
執行:	java 包名.類名

如:hello類(帶package且import了world類),world類(帶package),要執行hello類-------> 必須先編譯world類,才能成功編譯hello類,最後可以執行hello類。
調用main方法,可以使用world.main(null);

訪問權限修飾符:
類 :只有public和default(不使用修飾符),,控制是否可以在包外訪問。
成員(變量和方法):
public : 所有地方。
private :只有位於同一個類才能訪問。
default: default表示能夠被同包的訪問。如果子類和父類是在同一個包裏,則子類能夠訪問,否則不行。
**protected:**與default範圍稍大,子類與父類不在同一個包也可以訪問到父類中的protected成員,
但若用 父類對象名.變量名 進行訪問則:
在這裏插入圖片描述
可以直接在子類中使用 變量名(父類中的變量名) 進行訪問!!成功!!
在這裏插入圖片描述

內部類與外部類:
外部類 與 內部類之間的關係<==>宿主 與 寄生蟲 之間的關係
一個宿主可以含有多個同種 (或不同種)的寄生蟲,所以宿主 不認識 寄生蟲,寄生蟲 很容易就識別出 宿主。
如:外部類outer和內部類inner
inner類中不能存在static成員

outer類與一般java類一樣只能用public和default 修飾,但inner類相當於outer的一個成員,可以使用的訪問權限修飾符有 public,protected,default,private,static【其中若爲private則不能在outer類的外部訪問,若沒有用static或private修飾則可以訪問到】。

outer類無法訪問(指:直接訪問:不帶對象名前綴)inner類的任何類型成員,inner類可以直接訪問outer類的任何類型成員(包括private修飾的成員)

inner類的對象在outer類以外的其他類中的正確創建方法:
新的inner對象 = 新的outer類.新的inner類

1.Outer.Inner in = new Outer().new Inner();
2.Outer out1 = new Outer();
  Outer.Inner in = Out1.new Inner();

當inner類與outer類中的全局變量重名時,在inner類依據就近原則訪問到的是inner類的變量(即使使用了this前綴),若要在inner類中訪問到outer類的同名變量,則使用

outer.this.變量名

進行訪問,即 【外部類類名.this.變量名】。

局部內部類:
一般的內部類是在outer類中且在其方法外定義的,局部內部類是在outer類的任意方法中定義的,且只能在定義其的方法中訪問到(進行使用)

繼承和多態:
正是因爲 繼承,纔可以多態。

父類People  擁有方法:eat()
子類Teacher 擁有方法:eat(),teach()
子類Student 擁有方法:eat(), study()

則多態是指:
People p = new Teacher()
使用子類的構造方法構造一個父類對象p,則對象p所佔內存空間是一個Teacher的內存空間,由p.eat()調用的方法是Teacher中重寫的方法【且該方法在父類People中必須存在】。
若想調用Teacher特有的teach()方法,則:((Teacher)p).teach() 進行調用,且p的本質是Teacher【因爲由其構造】,所以不能使用上述方法調用Student中的特有方法。

抽象類:
abstract前綴:
1.抽象類中可以沒有抽象方法,但抽象方法只能存在於抽象類中
2.不能使用抽象類的構造方法進行類的實例化【但可以在在抽象類中寫構造方法?爲了方便子類調用繼承而來的構造方法來對繼承的屬性進行初始化】
3.抽象類的子類繼承該抽象類【爲實現父類中的抽象方法或調用方法】後,則子類中直接擁有了父類中的抽象方法且必須對這些abstract方法賦予方法體,否則是殘缺的類(含abstract方法)從而不能調用其構造方法實例對象。
4.abstract類A,其子類B,則可以:

A a =new B();
a.xx();

來調用B中【重寫或實現】的方法(A中需擁有該方法),或A中本來就有的非abstract方法。
5.抽象類可以繼承抽象類,知道一個完整的類繼承了其父抽象類爲止,則該完整的子類必須實現父抽象,爺爺抽象等抽象類中直到其父抽象類中沒有實現的所有抽象方法。

接口:
接口裏只能包含抽象方法–>是完全抽象的類,裏面沒完整方法
通過接口定義一些功能,其他類通過實現該接口來擁有並擴展功能。
接口可以被實現,也可以被另一個接口繼承【接口中可以有變量和抽象的方法
接口可以被抽象類實現,也可以被具體類實現
Java單繼承,多實現

多實現的情況:
interface中默認的方法 訪問權限修飾符 是public,在其子類中的實現方法至少爲public。。
如interface的A和B,和實現其方法的C:
在這裏插入圖片描述
在這裏插入圖片描述
採用的多態方法構建interface的對象時,使用new C()的構造方式進行構造,則其本質就是類C,但由於構造出的實例變量是A a,則會調用類A中的方法,之後將該實例變量強制轉換爲某類X,就會調用某類X的方法,,同樣的下面看 關於父子類的方法調用

public class Test39 {
public static void main(String[] args) {
Base a = new DerivedA();
a.test();//調用類Base中的方法,但test()被重寫了,輸出DerivedA中的test()
a.testBase();
System.out.println(a);//test.DerivedA@15db9742

Base b = new DerivedB();
b.test();//調用類Base中的方法,但test()被重寫了,輸出DerivedB中的test()
b.testBase();
System.out.println(b);//test.DerivedB@6d06d69c

((DerivedA)b).test();//調用類DerivedA中的test(),但DerivedB將其重寫了,輸出DerivedB中的test()
((DerivedA)b).testBase();//調用類Base中的方法,原因是DerivedA中繼承了該方法

((Base)b).test();//調用Base的方法,被DerivedB重寫則調用了DerivedB的test()
((Base)b).testBase();//調用Base的特有方法

((DerivedB)b).test();//調DerivedB
((DerivedB)b).testBase(); //用強轉DerivedA相似
}
}

class Base{
	public void testBase() {
		System.out.println("Base特有的方法");
	}
	public void test() {
		System.out.println("Base ");
	}
}
class DerivedA extends Base{
	public void test() {
		System.out.println("DerivedA ");
	}
}

class DerivedB extends DerivedA{
	public void test() {
		System.out.println("DerivedB ");
	}
}

與接口類方法調用規則的新鮮之處在於,子類進行調用時,還可以調用從父類繼承的方法;父類進行調用時,若其本質子類中重寫了該方法。則調用其本質子類中的該方法。

匿名內部類:
一個 接口interface 或 抽象類 Product類 ,使用一個實現其的子類 或 繼承其的子類,該子類沒有類名其實現完方法後立刻被調用,則該子類爲匿名內部類。

interface Product{
	String getName();
}
在其他類的方法中:
System.out.println(
	new Prodect(xxxx){
		public String getName(){
			return "Apple";
			}
		}.getName()  //此處沒有  分號!
	);

其中的匿名內部類也可作爲參數傳給 Product p 的參數類型,匿名內部類構造方法中的xxxx可以直接傳給 抽象父類Product 中的構造方法進行子類的初始化。。

Object類:
其中含有的 toString() 方法默認的作用是取得對象的內存地址(引用),含有的equals()方法默認是將對象的內存地址進行比較,
而String中的equals()方法已經被重寫過了,所以比較時比較的是String的值。若對自己自創的類調用equals()方法想比較值,需要自己重寫equals方法。

Scanner:
如Scanner的hasNextInt()判斷用戶輸入的下一個是不是整數,通過對hasNextInt(),next(),nextInt()進行調用,可確保輸入的值一定是一個整數,否則不接取。

StringBuffer:
.append()調用完返回的是自身—>可以鏈式編程(不斷調用.append()方法 ),返回的引用與原引用相同。
StringBuffer有初始容量,佔滿後會申請一個更大的內存空間,引用指向這個更大的內存空間【新的內存空間是原內存空間的2倍以上】,原內存空間中的數據被複制到新的內存空間中。
初始容量capacity由初始數據量大小或設置的capacity決定,擴容後的大小與原容量大小有關係。
String不可變【不能通過append在原內存空間裏直接銜接或delete直接刪除部分字符串】,StringBuffer與StringBuilder可變。
字符串的存儲,在內存中,JDK9之前使用char數組存儲,JDK9中使用byte數組存儲(佔用的內存空間更小)。

StringBuffer和StringBuilder的聯繫:
都可創建一個可以修改的字符串,使用起來基本相同【包含的函數基本一樣】。
不同:
StringBuffer線程安全,但性能略低
StringBuilder線程不安全但性能略高
所以在單線程的程序中一般使用StringBuilder,在多線程的程序中一般使用StringBuffer。

Arrays:
Arrays.sort()對數值型數組進行默認的升序排序。
Arrays.binarySearch(數組a, key值) 使用二分法搜索指定的key值,必須在此調用前使用sort()方法對a數組進行排序
如果沒有排序,則結果是不確定的()【小的數值可以查找到但index按升序sort後的index且忽略相同值佔用的index個數,大的數值返回未知負數】,
若a中包含多個key值元素,則無法保證找到的是哪一個【排序後可保證能找到,但不一定是升序中第一個符合的index】。

Math:
Math.E 自然底數
Math.ceil() 向上取整 |Math.floor() 向下取整 |Math.random() *控制個數,+控制範圍

**BigDecimal:**大小數
//此處傳遞的精度是不受限制的,只推薦這一種聲明方式
BigDecimal number = new BigDecimal(“0.00000000001”);
使用 BigDecimal.valueOf(double數) 聲明時函數會對其精度進行調整更精確,但不推薦。
BigInteger:大整數,用法與BigDecimal相似。

Date和Calendar:
Date存在缺陷,其中大部分方法被廢棄,Calendar是Date的升級版。
Date d = new Date(); print(d);–>輸出當前時間
Calendar calendar = Calendar.getInstance(); print(calendar);
---->輸出當前時間(較上面的 d 更加詳細)
print:calendar.get(Calendar.YEAR); —>輸出當前年份
其他常量參數可輸出calendar的其他信息!

拆箱和裝箱:
拆箱:基本類型包裝類對象—>基本類型
裝箱:基本類型 ---->包裝類對象
如:

Integer i =100;//裝箱 等價於 Integer i = Integer.valueOf(100);  自動的裝箱過程
i = i + 100;//先拆箱後裝箱 <==> i = i.intValueOf() +100; 拆箱得200後再裝箱爲對象 
System.out.println(i); //toString早被重寫過了,輸出200
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章