Java中容易被你忽略的細節(jié)(一)

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方法眷蜓。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市胎围,隨后出現(xiàn)的幾起案子吁系,更是在濱河造成了極大的恐慌德召,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件汽纤,死亡現(xiàn)場離奇詭異上岗,居然都是意外死亡,警方通過查閱死者的電腦和手機蕴坪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門肴掷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人背传,你說我怎么就攤上這事呆瞻。” “怎么了径玖?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵痴脾,是天一觀的道長。 經(jīng)常有香客問我梳星,道長明郭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任丰泊,我火速辦了婚禮,結(jié)果婚禮上始绍,老公的妹妹穿的比我還像新娘瞳购。我一直安慰自己,他們只是感情好亏推,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布学赛。 她就那樣靜靜地躺著,像睡著了一般吞杭。 火紅的嫁衣襯著肌膚如雪盏浇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天芽狗,我揣著相機與錄音绢掰,去河邊找鬼。 笑死童擎,一個胖子當著我的面吹牛滴劲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顾复,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼班挖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了芯砸?” 一聲冷哼從身側(cè)響起萧芙,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤给梅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后双揪,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體动羽,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年盟榴,在試婚紗的時候發(fā)現(xiàn)自己被綠了曹质。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡擎场,死狀恐怖羽德,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迅办,我是刑警寧澤宅静,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站站欺,受9級特大地震影響姨夹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矾策,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一磷账、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贾虽,春花似錦逃糟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至地粪,卻和暖如春取募,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蟆技。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工玩敏, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人付魔。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓聊品,卻偏偏與公主長得像,于是被迫代替她去往敵國和親几苍。 傳聞我的和親對象是個殘疾皇子翻屈,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法妻坝,內(nèi)部類的語法伸眶,繼承相關的語法惊窖,異常的語法,線程的語...
    子非魚_t_閱讀 31,598評論 18 399
  • (一)Java部分 1厘贼、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,080評論 0 62
  • 轉(zhuǎn)自:http://blog.csdn.net/jackfrued/article/details/4492194...
    王帥199207閱讀 8,504評論 3 93
  • 曾經(jīng)嘴秸,我也是單純而溫暖的女子毁欣,相信這個世上有愛,有純粹的愛岳掐。只是凭疮,如今的自己,早已不復當年模樣串述。 其實执解,我多么的...
    紅色小星閱讀 287評論 8 4
  • 一、目標實現(xiàn)在Linux下用Pycharm調(diào)試工具/Python開發(fā)Linux使用vi/vim工具寫Python纲酗,...
    玖月初識閱讀 5,473評論 0 2