1.Java中的條件運算符
條件運算符是"? : "是Java中唯一一個三目運算符甸饱,格式為:
表達式1 冕象?表達式2 : 表達式3【Java學習資料免費分享微信:tangniu520666任柜,備注“4”】
表達式1的類型必須是boolean類型(或者是可以通過拆箱轉(zhuǎn)換為boolean類型的Boolean類型)
备徐,當表達式1的值為true時寓盗,條件表達式的結(jié)果就是表達式2的值叮阅,為false時,結(jié)果為表
達式3的值龄句。表達式2與表達式3的類型可以是任意類型回论。根據(jù)表達式2與表達式3的類型
不同,條件表達式的類型也會隨之不同分歇。具體的判斷如下:
1.如果二者(表達式2與表達式3)的類型形同透葛,條件表達式的類型為表達式2(表達式3)的類型
2.如果二者之一類型為boolean,另外一個類型為Boolean,"?:"的類型為boolean
3.如果二者之一為引用常量null,則:
1)如果另外一個為引用類型卿樱,條件表達式的類型為引用類型
2)如果另外一個為基本數(shù)據(jù)類型,條件表達式的類型為基本數(shù)據(jù)類型對應的包裝類型硫椰,
即基本數(shù)據(jù)類型裝箱后的類型繁调。
4.如果二者為除boolean外的基本數(shù)據(jù)類型(或者基本數(shù)據(jù)類型對應的包裝類型)萨蚕,則條件
表達式的類型為基本數(shù)據(jù)類型中的一種(不包括boolean)
總結(jié):根據(jù)表達式2與表達式3的類型不同,條件表達式的類型也會不同蹄胰。
2.在Java運算中岳遥,存在一些關系到順序的計算,這些計算順序在C/C++語言中是不確定的裕寨,
并且最后的結(jié)果也沒有保障浩蓉。而Java不同,Java經(jīng)過編譯之后宾袜,生成的是與平臺無關的
字節(jié)碼捻艳,并且交互對象是Java虛擬機,與底層的硬件環(huán)境無關庆猫,這些運算在Java中是
確定的认轨。在Java中,操作數(shù)的計算順序是從左向右的月培,也就是首先計算左側(cè)的操作數(shù)嘁字,
然后再計算其右側(cè)的操作數(shù)。操作數(shù)從左向右的計算規(guī)則與運算符的結(jié)合性無關杉畜,就算
運算符是由右向左結(jié)合的纪蜒,也會在運算之前確定左側(cè)的操作數(shù)。
符合運算符可以自動將右側(cè)運算結(jié)果類型轉(zhuǎn)換為左側(cè)操作數(shù)的類型此叠。
如:byte b=1;
b=b+1; //錯誤 因為1是int類型的
b+=1; //正確纯续,相當于b=(byte)(b+1);
3.在Java中交換變量的三種方式:
1).int temp;
temp=a;
a=b;
b=temp;
2).a=a+b;
b=a-b;
a=a-b;
3).a=a^b;
b=a^b;
a=a^b;
/**
位異或(^)運算有這樣的性質(zhì),就是兩個整型數(shù)據(jù)x與y,有:
(x^y^y)=x
就是如果一個變量x異或另外一個變量y兩次拌蜘,結(jié)果為x.
*/
4.Java中的Switch語句:
switch表達式可以是byte,short,char,int,以及它們對應的包裝類Byte,Short,Character,
Integer類型杆烁,也可以是枚舉類型,String類型简卧。
switch(表達式)
{
case 常量表達式或枚舉常量名1:
語句;
......
default:
語句兔魂;
}
case語句可以有0-n個,default語句可以有0個或1個举娩。另外任意兩個case表達式的值
不允許相同析校,case常量表達式或枚舉常量的值必須可賦值給switch表達式的類型。
switch語句處理包裝類:都是將包裝類型間接轉(zhuǎn)換為基本數(shù)據(jù)類型處理铜涉,然后進行
case相等的比較智玻。(包裝類型拆箱為基本數(shù)據(jù)類型)
switch語句處理枚舉類型:對于枚舉類型,首先會在內(nèi)部生成一個匿名類芙代,該匿名類
含有一個int[]類型的靜態(tài)final成員變量吊奢,數(shù)組的長度為枚舉常量的個數(shù),數(shù)組元素
的值為枚舉常量的序數(shù)(ordinal方法返回的值),然后通過該數(shù)組元素的值來進行選擇纹烹。
switch對枚舉進行處理時页滚,輔助的靜態(tài)匿名類(含有靜態(tài)成員)是由編譯器生成召边。如果
我們自己在程序中聲明匿名類,類中不允許有靜態(tài)成員裹驰。
枚舉類的Values方法返回該枚舉類型的數(shù)組隧熙,數(shù)組包含該枚舉類所有的枚舉常量。每個
枚舉常量都有一個序數(shù)幻林,從0開始贞盯,依次遞增,順序與聲明枚舉類時枚舉常量在枚舉類
中出現(xiàn)的順序一致沪饺□锔遥可以使用ordinal方法獲得該序數(shù),并且為數(shù)組元素依次賦值随闽,
從1開始父丰。
switch語句對String的處理:當switch表達式是String類型的時候,會將switch語句拆分
成兩個switch語句來處理掘宪,第一個switch語句根據(jù)對象的哈希碼來對一個臨時變量賦值蛾扇,
第二個switch語句根據(jù)該變量的值來匹配case表達式的值。
當switch類型為String類型時魏滚,將switch語句拆分為兩個switch語句镀首,分別對String對象
的哈希碼及臨時變量來輔助完成。
5.在Java中鼠次,使用"+"來連接兩個字符串更哄。當"+"兩邊的操作數(shù)是String類型時(如果只有
一個操作數(shù)是String類型,則系統(tǒng)也會將另外一個操作數(shù)轉(zhuǎn)換為String類型)腥寇,就會執(zhí)行
字符串連接運算成翩。
當使用"+"對字符串進行連接時,會創(chuàng)建一個臨時的StringBuilder對象赦役,該對象調(diào)用
append方法負責字符串的連接操作麻敌,然后再調(diào)用StringBuilder類的toString方法轉(zhuǎn)換
成String對象。
String s1="Hello";
String s2="World!";
System.out.println(s1+s2);
可以認為實際的代碼是這樣的:
System.out.println((new StringBuilder()).append(s1).append(s2).toString());
當使用運算符"+"連接字符串時掂摔,如果兩個操作數(shù)都是編譯時常量术羔,則在編譯時期就會
計算出該字符串的值,而不會在運行的時候創(chuàng)建StringBuilder對象乙漓。
"+"的性能:如果只是簡單幾個字符串的連接级历,使用"+"運算符是非常方便的,但是
在循環(huán)中反復執(zhí)行String對象的連接操作叭披,性能就會變差寥殖,因此建議直接使用
StringBuilder來代替"+"的連接,這樣可以省去每次系統(tǒng)創(chuàng)建StringBuilder類的開銷。
6.System類的nanoTime方法:
long start=System.nanoTime;
long end=System.nanoTime();
long time=end-start;
System.out.println(time);
System類的nanoTime方法返回從某個時間開始所經(jīng)歷的納秒數(shù)扛禽,這個時間可以是過去锋边,
也可以是未來。如果是未來编曼,則返回負數(shù)值。該方法不是系統(tǒng)時鐘剩辟,但是可以用來
計算所經(jīng)歷的時間長度掐场。
7.String類型是引用類型,String對象一經(jīng)修改贩猎,就不能修改熊户。String類是final類型的,
我們無法繼承該類吭服,并且其所有的成員變量都是私有的(private),沒有提供修改私有
成員變量的公有(public)方法嚷堡。
String的所有數(shù)據(jù)成員都是私有的,并且沒有提供修改數(shù)據(jù)成員的方法艇棕,String內(nèi)部使用
一個char類型的數(shù)組來維護字符序列蝌戒,所有對字符序列的操作都是在一個新創(chuàng)建的String
對象上面進行的,而不是在該對象本身維護的數(shù)組上進行的沼琉。當對String對象調(diào)用某些
方法時北苟,就會創(chuàng)建一個新的String對象。
String類那些看似修改字符序列的方法實際上都是返回新創(chuàng)建的String對象打瘪,而不是
修改自身對象友鼻。由于String對象是不可改變的,因此其具有線程安全性闺骚,可以自由地
實現(xiàn)共享彩扔。
8.在Java中的String類中,是使用一個字符數(shù)組來維護字符序列的僻爽,其聲明如下:
private final char value[];
String的最大長度取決于字符數(shù)組的最大長度虫碉,在指定數(shù)組長度時,可以使用byte,short,
char,int類型进泼,而不能夠使用long類型蔗衡,數(shù)組的最大長度就是int類型的最大值,
即0x7fffffff,十進制就是2147483647乳绕,這也就是String所能容納的最大字符數(shù)量绞惦,獲得
String對象長度的length方法返回的是int類型的,而不是long類型的洋措。而這個最大值
只是理論上能夠到達的值济蝉。
Java中的對象是分配在堆上的贺嫂,堆的大小直接決定我們所能創(chuàng)建對象的多少,堆越大雁乡,
所能創(chuàng)建的對象越多第喳。因此,我們只要改變堆的大小踱稍,就能改變所能創(chuàng)建對象的多少曲饱。
在Java中,默認的堆空間的最大值是256MB啤挎。
9.String字面常量的最大長度與String在內(nèi)存中的最大長度是不一樣的驻谆,后者的
最大長度為int類型的最大值,即2147483647,而前者根據(jù)字符(字符Unicode值)的不同庆聘,
最大長度也不同胜臊,最大值為65534(可手動修改class文件,令輸出結(jié)果為65535)掏觉。
String字面常量的最大長度是由CONSTANT_Utf8_info表來決定的区端,該長度在編譯時確定
如果超過CONSTANT_Utf8_info表bytes數(shù)組所能表示的上限,就會產(chǎn)生編譯錯誤澳腹。
10.Java中equals方法與"=="的區(qū)別:
equals比較的是兩個對象的內(nèi)容是否相等
==:比較的是兩個對象(地址)是否是同一個對象(對象地址是否相等)
equals方法是在Object類中聲明的织盼,訪問修飾符為public,而所有類(除Object自身外)
都是Object的直接或間接子類酱塔,也就是所有子類的繼承了這個方法沥邻。
在Object類中,equals方法實現(xiàn)如下:
public boolean equals(Object obj)
{
return (this==obj);
}
在Object中羊娃,equals方法與"=="運算符是完全等價的唐全。對于String類,之所以該類可以
比較對象的內(nèi)容蕊玷,那是因為String類重寫了equals方法邮利,使該方法比較的是字符序列(內(nèi)容)
在Java API文檔中,equals的重寫規(guī)則:
1.自反性垃帅。對于任何非null的引用值x,x.equals(x)應返回true.
2.對稱性延届。對于任何非null的引用值x與y,當且僅當:y.equals(x)返回true時,
x.equals(y)才應返回true.
3.傳遞性贸诚。對于任何非null的引用值x,y與z,如果x.equals(y)返回true,并且y.equals(z)
返回true,那么x.equals(z)也應該返回true.
4.一致性方庭。對于任何非null的引用值x與y,假設對象上equals比較中的信息沒有被修改厕吉,
則多次調(diào)用x.equals(y)始終返回true或始終返回false.
5.對于任何非空引用值x,x.equals(null)應返回false.
在重寫equals方法的同時械念,也必須重寫hashCode方法头朱,否則該類與其他類(如實現(xiàn)了Map
接口或其子接口的類)交互時,很可能產(chǎn)生不確定的運行結(jié)果龄减。
11.在Java API文檔中项钮,關于hashCode方法的幾點規(guī)定:
1).在Java應用程序執(zhí)行期間,如果在對象equals方法比較中所用的信息沒有被修改欺殿,
那么在同一對象上多次調(diào)用hashCode方法時寄纵,必須一致地返回相同的整數(shù)。但如果多次
執(zhí)行同一個應用時脖苏,不要求該整數(shù)必須相同。
2).如果兩個對象通過調(diào)用equals方法是相等的定踱,那么這兩個對象調(diào)用hashCode方法必須
返回相同的整數(shù)棍潘。
3).如果兩個對象通過調(diào)用equals方法是不相等的,不要求這兩個對象調(diào)用hashCode方法
必須返回不同的整數(shù)崖媚。
在Object類中亦歉,hashCode方法是通過Object對象地址計算出來的,因為Object對象只與
自身相等畅哑,故同一個對象的地址總是相等的肴楷,計算取得的hashCode碼也必然相等。對于
不同的Object對象荠呐,地址不同赛蔫,hashCode碼也不會相同。
12.Java中String類中泥张,存在一個專門的區(qū)域呵恢,用于存儲String字面常量,這個區(qū)域稱為
常量池媚创。常量池由String類進行維護渗钉。
當需要將某個String對象加入常量池中時,就可以調(diào)用intern方法來完成钞钙,這個操作也
稱作拘留字符串鳄橘,系統(tǒng)會自動將String字面常量與String表達式的字符串值加入常量池
中,這也是通過調(diào)用intern方法來實現(xiàn)的芒炼。當String對象調(diào)用intern方法時瘫怜,如果
常量池中已經(jīng)含有該對象(通過equals方法來判斷),則返回常量池中的String對象。如果
不存在焕议,則將該對象加入常量池中宝磨,并返回該對象弧关。
String對象是不可改變的,因此沒必要創(chuàng)建兩個相同的String對象唤锉。只需要將String
對象加入常量池世囊,在需要時取出,這樣既可實現(xiàn)String對象的共享窿祥。在程序中出現(xiàn)String
編譯常量(String字面常量與String常量表達式)時株憾,會自動調(diào)用intern方法,如果常量池
中含有相等的String對象晒衩,則直接返回常量池中的對象嗤瞎,否則將對象加入常量池中并返回
該對象。對于運行時創(chuàng)建的String對象(非String編譯時常量)听系,會分配到堆中贝奇,系統(tǒng)不會
自動調(diào)用intern方法拘留該對象,不過我們依然可以自行調(diào)用該對象的intern方法對該
對象進行拘留靠胜。
13.main方法是Java程序的入口點掉瞳,由Java虛擬機自動調(diào)用。main方法的聲明:
public static void main(String[] args)或者
public static void main(String args[])
main方法是公有的(public),靜態(tài)的(static),返回類型為void,這樣聲明的原因如下:
public:main方法作為應用程序的入口浪漠,該方法是在程序啟動時由Java虛擬機調(diào)用的陕习,
所有應該聲明為public.
static:如果不是靜態(tài)的方法,就需要通過對象來訪問址愿。而當Java程序運行该镣,虛擬機調(diào)用
main方法的時候,沒有必要創(chuàng)建含有main方法類的對象响谓。
void:main方法在退出時损合,并沒有給系統(tǒng)返回退出代碼,而是在需要時使用
System.exit(int status)方法來返回歌粥,所以返回類型為void.
String[] args:該字符串數(shù)組用來在運行時接收用戶輸入的參數(shù)塌忽,具體長度取決于用戶
輸入?yún)?shù)的個數(shù),如果用戶沒有輸入?yún)?shù)失驶,那么args數(shù)組長度為0
(并非為null).
JDK1.5后土居,main方法的args參數(shù)也可以使用可變參數(shù)類型,聲明如下:
public static void main(String...args).
main方法與很多方法的相似之處:
1.main方法的重載(main方法也可重載)
2.調(diào)用main方法(其他方法也可以調(diào)用main方法)
3.繼承main方法(main方法也是可以由子類繼承)
4.隱藏main方法(子類可以隱藏父類的main方法)
5.main方法也可以拋出異常
6.main方法也可以帶有類型參數(shù)
如果子類繼承類父類的main方法嬉探,并且在子類中重寫聲明新的main方法擦耀,也可以隱藏父
類的main方法,這個表現(xiàn)與隱藏其他方法是一樣的涩堤。
也可以通過反射機制來調(diào)用main方法眷蜓。