重新認(rèn)識java(一) ---- 萬物皆對象

如果你現(xiàn)實(shí)中沒有對象精绎,至少你在java世界里會(huì)有茫茫多的對象澈吨,聽起來是不是很激動(dòng)呢更胖?

對象艘狭,引用唾那,類與現(xiàn)實(shí)世界

現(xiàn)實(shí)世界里有許許多多的生物霜医,非生物线衫,跑的跳的飛的啡氢,過去的現(xiàn)在的未來的菩暗,令人眼花繚亂掰曾。我們編程的目的,就是解決現(xiàn)實(shí)生活中的問題停团。所以不可避免的我們要和現(xiàn)實(shí)世界中各種奇怪的東西打交道旷坦。

在現(xiàn)實(shí)世界里掏熬,你新認(rèn)識了一個(gè)朋友,你知道他長什么樣秒梅,知道了他的名字年齡旗芬,地址。知道他喜歡干什么有什么特長捆蜀。你想用java語言描述一下這個(gè)人疮丛,你應(yīng)該怎么做呢?

這個(gè)時(shí)候辆它,就有了類的概念誊薄。每一個(gè)類對應(yīng)現(xiàn)實(shí)世界中的某一事物。比如現(xiàn)實(shí)世界中有人锰茉。那么我們就創(chuàng)建一個(gè)關(guān)于“人”的類暇屋。

每一個(gè)人都有名字,都有地址等等個(gè)人信息洞辣。那么我們就在“人”的類里面添加這些屬性咐刨。

每一個(gè)人都會(huì)吃,會(huì)走路扬霜,那么我們就在“人”的類里面添加吃和走的方法定鸟。

當(dāng)這個(gè)世界又迎來了一個(gè)新生命,我們就可以“new”一個(gè)“人”著瓶,“new”出來的就叫”對象“联予。

每一個(gè)人一出生,父母就會(huì)給他取個(gè)名字材原。在程序里沸久,我們需要用一種方式來操作這個(gè)“對象”,于是余蟹,就出現(xiàn)了引用卷胯。我們通過引用來操作對象,設(shè)置對象的屬性威酒,操作對象的方法窑睁。

這就是最基本的面向?qū)ο蟆?/p>

現(xiàn)實(shí)世界的事物】 ---抽象---> 【 】---new--->【對象 】<---控制--- 【引用

從創(chuàng)建一個(gè)對象開始

創(chuàng)建對象的前提是先得有一個(gè)類。我們先自己創(chuàng)建一個(gè)person類葵孤。

//Person類
public class Person {
    private String name;
    private int age;

    public void eat(){
        System.out.println("i am eating");
    }
}

創(chuàng)建一個(gè)person對象担钮。

    Person p = new Person();

怎么理解這句簡單的代碼呢?

  • new Person :一個(gè)Person類型的對象
  • () : 這個(gè)括號相當(dāng)于調(diào)用了person的無參構(gòu)造方法
  • p : Person對象的引用

有的人會(huì)認(rèn)為p就是new出來的Person對象尤仍。這是錯(cuò)誤的理解箫津,p只是一個(gè)Person對象的引用而已。那么問題來了,什么是引用苏遥?什么又是對象呢送挑?這個(gè)要從內(nèi)存說起。

創(chuàng)建對象的過程

java大體上會(huì)把內(nèi)存分為四塊區(qū)域:堆暖眼,棧惕耕,靜態(tài)區(qū),常量區(qū)诫肠。

  • 堆 : 位于RAM中司澎,用于存放所有的java對象。
  • 棧 : 位于RAM中栋豫,引用就存在于棧中挤安。
  • 靜態(tài)區(qū) : 位于RAM中,被static修飾符修飾的變量會(huì)被放在這里
  • 常量區(qū) :位于ROM中丧鸯, 很明顯蛤铜,放常量的。

事實(shí)上丛肢,我們不需要關(guān)心java的對象围肥,變量到底存在了哪里,因?yàn)閖vm會(huì)幫我們處理好這些蜂怎。但是理解了這些穆刻,有助于提高我們的水平。

當(dāng)執(zhí)行這句代碼的時(shí)候杠步。

Person p = new Person();

首先氢伟,會(huì)在堆中開辟一塊空間存放這個(gè)新來的Person對象。然后幽歼,會(huì)創(chuàng)建一個(gè)引用p朵锣,存放在棧中,這個(gè)引用p指向Person對象(事實(shí)上是甸私,p的值就是Person對象的內(nèi)存地址)诚些。

這樣,我們通過訪問p颠蕴,然后得到了Person的內(nèi)存地址泣刹,進(jìn)而找到了Person對象。

然后又有了這樣一句代碼:

Person p2 = p;

這句代碼的含義是:
創(chuàng)建了一個(gè)新的引用犀被,保存在棧中,引用的地址也指向Person的地址外冀。這個(gè)時(shí)候寡键,你通過p2來改變Person對象的狀態(tài),也會(huì)改變p的結(jié)果雪隧。因?yàn)樗鼈冎赶蛲粋€(gè)對象西轩。(String除外员舵,之后會(huì)專門講String)

此時(shí),內(nèi)存中是這樣的:

用一種很通俗的方式來講解一下引用和對象藕畔。

大家都應(yīng)該用過windows吧马僻。win有一個(gè)神奇的東西叫做快捷方式。我們桌面的圖標(biāo)大部分都是快捷方式注服。它并不是我們安裝在電腦上的應(yīng)用的可執(zhí)行文件(不是.exe文件)韭邓,那么為什么點(diǎn)擊它可以打開應(yīng)用程序呢?這個(gè)我不用講了把溶弟。

我們的對象和引用就和快捷方式和它連接的文件一樣女淑。

我們不直接對文件進(jìn)行操作,而是通過快捷方式來進(jìn)行操作辜御⊙寄悖快捷方式不能獨(dú)立存在,同樣擒权,引用也不能獨(dú)立存在(你可以只創(chuàng)建一個(gè)引用袱巨,但是當(dāng)你要使用它的時(shí)候必須得給它賦值,否則它將毫無用處)碳抄。

一個(gè)文件可以有多個(gè)快捷方式瓣窄,同樣一個(gè)對象也可以有多個(gè)引用。而一個(gè)引用只能同時(shí)對應(yīng)一個(gè)對象纳鼎。

在java里俺夕,“=”不能被看成是一個(gè)賦值語句,它不是在把一個(gè)對象賦給另外一個(gè)對象贱鄙,它的執(zhí)行過程實(shí)質(zhì)上是將右邊對象的地址傳給了左邊的引用劝贸,使得左邊的引用指向了右邊的對象。java表面上看起來沒有指針逗宁,但它的引用其實(shí)質(zhì)就是一個(gè)指針映九。在java里,“=”語句不應(yīng)該被翻譯成賦值語句瞎颗,因?yàn)樗鶊?zhí)行的確實(shí)不是一個(gè)簡單的賦值過程件甥,而是一個(gè)傳地址的過程,被譯成賦值語句會(huì)造成很多誤解哼拔,譯得不準(zhǔn)確引有。

特例:基本數(shù)據(jù)類型

為什么會(huì)有特例呢?因?yàn)橛胣ew操作符創(chuàng)建的對象會(huì)存在堆里倦逐,二在堆里開辟空間等行為效率較操作棧要低譬正。而我們平時(shí)寫代碼的時(shí)候會(huì)經(jīng)常創(chuàng)建一些“小變量”,比如int i = 1;如果每次都用Interger來new一個(gè)曾我,效率不是很高而且浪費(fèi)內(nèi)存粉怕。

所以針對這些情況,java提供了“基本數(shù)據(jù)類型”抒巢,基本數(shù)據(jù)類型一共有八種贫贝,每一個(gè)基本數(shù)據(jù)類型存放在棧中,而他們的值存放在常量區(qū)中蛉谜。

舉個(gè)例子:

int i = 2;
int j = 2;

我們需要知道的是稚晚,在常量區(qū)中,相同的常量只會(huì)存在一個(gè)悦陋。當(dāng)執(zhí)行第一句代碼時(shí)蜈彼。先查找常量區(qū)中有沒有2,沒有俺驶,則開辟一個(gè)空間存放2幸逆,然后在棧中存入一個(gè)變量i,讓i指向2暮现;

執(zhí)行第二句的時(shí)候还绘,查找發(fā)現(xiàn)2已經(jīng)存在了,所以就不開辟新空間了栖袋。直接在棧中保存一個(gè)新變量j拍顷,讓j指向2;

當(dāng)然塘幅,java堆每一個(gè)基本數(shù)據(jù)類型都提供了對應(yīng)的包裝類昔案。我們依舊可以用new操作符來創(chuàng)建我們想要的變量。

Integer i = new Integer(1);
Integer j = new Integer(1);

但是电媳,用new操作符創(chuàng)建的對象是不同的踏揣,也就是說,此時(shí)匾乓,i和j指向不同的內(nèi)存地址捞稿。因?yàn)槊看握{(diào)用new操作符,都會(huì)在堆開辟新的空間拼缝。

當(dāng)然娱局,說到基本數(shù)據(jù)類型,不得不提一下java的經(jīng)典設(shè)計(jì)咧七。

先看一段代碼:

為什么一個(gè)是true一個(gè)是false呢衰齐?

我就不講了,應(yīng)該都知道吧猪叙。我就貼一個(gè)Integer的源碼(jdk1.8)吧娇斩。

Integer 類的內(nèi)部定義了一個(gè)內(nèi)部類仁卷,緩存了從-128到127的所有數(shù)字穴翩,所以犬第,你懂得。

又一個(gè)特例 :String

String是一個(gè)特殊的類芒帕,因?yàn)樗籪inal修飾符所修飾歉嗓,是一個(gè)不可改變的類。當(dāng)然背蟆,看過java源碼后你會(huì)發(fā)現(xiàn)鉴分,基本類型的各個(gè)包裝類也被final所修飾。這里以String為例带膀。

我們來看這樣一個(gè)例子

執(zhí)行第一句 : 常量區(qū)開辟空間存放“abc”志珍,s1存放在棧中指向“abc”

執(zhí)行第二句,s2 也指向 “abc”垛叨,

執(zhí)行第三句伦糯,因?yàn)椤癮bc”已經(jīng)存在,所以直接指向它嗽元。

所以三個(gè)變量指向同一塊內(nèi)存地址敛纲,結(jié)果都為true。

當(dāng)s1內(nèi)容改變的時(shí)候剂癌。這個(gè)時(shí)候淤翔,常量區(qū)開辟新的空間存放“bcd”,s1指向“bcd”佩谷,而s2和s3指向“abc”所以只有s2和s3相等旁壮。

這種情況下,s1,s2,s3都是字符串常量谐檀,類似于基本數(shù)據(jù)類型抡谐。(如果執(zhí)行的是s1 = "abc",那么結(jié)果會(huì)都是true)

我們再看一個(gè)例子:

執(zhí)行第一行代碼: 在堆里分配空間存放String對象,在常量區(qū)開辟空間存放常量“abc”稚补,String對象指向常量童叠,s1指向該對象。

執(zhí)行第二行代碼:s2指向上一步new出來的string對象课幕。

執(zhí)行第三行代碼: 在堆里分配新的空間存放String對象厦坛,新對象指向常量“abc”,s3指向該對象乍惊。

到這里杜秸,很明顯,s1和s2指向的是同一個(gè)對象

接著就很詭異了润绎,我們讓s1 依舊= “abc",但是結(jié)果s1和s2指向的地址不同了撬碟。

怎么回事呢诞挨?這就是String類的特殊之處了,new出來的String不再是上面的字符串常量呢蛤,而是字符串對象惶傻。

由于String類是不可改變的,所以String對象也是不可改變的其障,我們每次給String賦值都相當(dāng)于執(zhí)行了一次new String()银室,然后讓變量指向這個(gè)新對象,而不是在原來的對象上修改励翼。

當(dāng)然蜈敢,java還提供了StringBuffer類,這個(gè)是可以在原對象上做修改的汽抚。如果你需要修改原對象抓狭,那么請使用StringBuffer類。

值傳遞和引用傳遞的戰(zhàn)爭

java是值傳遞還是引用傳遞的呢造烁?毫無疑問否过,java是值傳遞的。那么什么又叫值傳遞和引用傳遞呢膨蛮?

我們先來看一個(gè)例子:

這是一個(gè)很經(jīng)典的例子叠纹,我們希望調(diào)用了swap函數(shù)以后,a和b的值可以互換敞葛,但是事實(shí)上并沒有誉察。為什么會(huì)這樣呢?

這就是因?yàn)閖ava是值傳遞的惹谐。也就是說持偏,我們在調(diào)用一個(gè)需要傳遞參數(shù)的函數(shù)時(shí),傳遞給函數(shù)的參數(shù)并不是我們傳進(jìn)去的參數(shù)本身氨肌,而是它的副本鸿秆。說起來比較拗口,但是其實(shí)原理很簡單怎囚。我們可以這樣理解:

一個(gè)有形參的函數(shù)卿叽,當(dāng)別的函數(shù)調(diào)用它的時(shí)候,必須要傳遞數(shù)據(jù)恳守。
比如swap函數(shù)考婴,別的函數(shù)要調(diào)用swap就必須傳兩個(gè)整數(shù)過來。

這個(gè)時(shí)候催烘,有一個(gè)函數(shù)按耐不住寂寞沥阱,扔了兩個(gè)整數(shù)過來,但是伊群,swap函數(shù)有潔癖考杉,它不喜歡用別人的東西策精,于是它把傳過來的參數(shù)復(fù)制了一份,然后對復(fù)制的數(shù)據(jù)修修改改崇棠,而別人傳過來的參數(shù)動(dòng)根本沒動(dòng)咽袜。

所以,當(dāng)swap函數(shù)執(zhí)行完畢之后易茬,交換了的數(shù)據(jù)只是swap自己復(fù)制的那一份酬蹋,而原來的數(shù)據(jù)沒變及老。

也可以理解為別的函數(shù)把數(shù)據(jù)傳遞給了swap函數(shù)的形參抽莱,最后改變的只是形參而實(shí)參沒變,所以不會(huì)起到任何效果骄恶。

我們再來看一個(gè)復(fù)雜一點(diǎn)的例子(Person類添加了get食铐,set方法):

可以看到,我們把p1傳進(jìn)去僧鲁,它并沒有被替換成新的對象虐呻。因?yàn)閏hange函數(shù)操作的不是p1這個(gè)引用本身,而是這個(gè)引用的一個(gè)副本寞秃。

你依然可以理解為斟叼,主函數(shù)將p1復(fù)制了一份然后變成了chagne函數(shù)的形參,最終指向新Person對象的是那個(gè)副本引用春寿,而實(shí)參p1并沒有改變朗涩。

再來看一個(gè)例子:

這次為什么就改變了呢?分析一下绑改。

首先谢床,new了一個(gè)Person對象,暫且叫他小明吧厘线。然后p1指向小明识腿。

小明10歲了,隨著時(shí)間的推移造壮,小明的年齡要變了渡讼,調(diào)用了一下changgeAge方法,把小明的引用傳了進(jìn)去耳璧。

傳遞的過程中成箫,changgeAge也有潔癖,于是復(fù)制了一份小明的引用楞抡,這個(gè)副本也指向小明伟众。

然后changgeAge通過自己的副本引用,改變了小明的年齡召廷。

由于是小明這個(gè)對象被改變了凳厢,所以所有小明的引用調(diào)用方法得到的年齡都會(huì)改變

所以就變了账胧。

最后簡單的總結(jié)一下。

java的傳值過程先紫,其實(shí)傳的是副本治泥,不管是變量還是引用。所以遮精,不要期待把變量傳遞給一個(gè)函數(shù)來改變變量本身居夹。

對象的強(qiáng)引用,軟引用本冲,弱引用和虛引用

Java中是JVM負(fù)責(zé)內(nèi)存的分配和回收准脂,這樣雖然使用方便,程序不用再像使用c那樣操心內(nèi)存檬洞,但同時(shí)也是它的缺點(diǎn)(不夠靈活)狸膏。為了解決內(nèi)存操作不靈活這個(gè)問題,可以采用軟引用等方法添怔。

先介紹一下這四種引用:

  • 強(qiáng)引用

以前我們使用的大部分引用實(shí)際上都是強(qiáng)引用湾戳,這是使用最普遍的引用。如果一個(gè)對象具有強(qiáng)引用广料,那就類似于必不可少的生活用品砾脑,垃圾回收器絕不會(huì)回收它。當(dāng)內(nèi)存空 間不足艾杏,Java虛擬機(jī)寧愿拋出OutOfMemoryError錯(cuò)誤韧衣,使程序異常終止,也不會(huì)靠隨意回收具有強(qiáng)引用的對象來解決內(nèi)存不足問題糜颠。

  • 軟引用(SoftReference)

    如果一個(gè)對象只具有軟引用汹族,那就類似于可有可物的生活用品。如果內(nèi)存空間足夠其兴,垃圾回收器就不會(huì)回收它顶瞒,如果內(nèi)存空間不足了,就會(huì)回收這些對象的內(nèi)存元旬。只要垃圾回收器沒有回收它榴徐,該對象就可以被程序使用。軟引用可用來實(shí)現(xiàn)內(nèi)存敏感的高速緩存匀归。

    軟引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用坑资,如果軟引用所引用的對象被垃圾回收,JAVA虛擬機(jī)就會(huì)把這個(gè)軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中穆端。

  • 弱引用(WeakReference)

    如果一個(gè)對象只具有弱引用袱贮,那就類似于可有可物的生活用品。弱引用與軟引用的區(qū)別在于:只具有弱引用的對象擁有更短暫的生命周期体啰。在垃圾回收器線程掃描它 所管轄的內(nèi)存區(qū)域的過程中攒巍,一旦發(fā)現(xiàn)了只具有弱引用的對象嗽仪,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存柒莉。不過闻坚,由于垃圾回收器是一個(gè)優(yōu)先級很低的線程, 因此不一定會(huì)很快發(fā)現(xiàn)那些只具有弱引用的對象兢孝。

    弱引用可以和一個(gè)引用隊(duì)列(ReferenceQueue)聯(lián)合使用窿凤,如果弱引用所引用的對象被垃圾回收,Java虛擬機(jī)就會(huì)把這個(gè)弱引用加入到與之關(guān)聯(lián)的引用隊(duì)列中跨蟹。

  • 虛引用(PhantomReference)

    "虛引用"顧名思義雳殊,就是形同虛設(shè),與其他幾種引用都不同喷市,虛引用并不會(huì)決定對象的生命周期相种。如果一個(gè)對象僅持有虛引用,那么它就和沒有任何引用一樣品姓,在任何時(shí)候都可能被垃圾回收。

    虛引用主要用來跟蹤對象被垃圾回收的活動(dòng)箫措。虛引用與軟引用和弱引用的一個(gè)區(qū)別在于:虛引用必須和引用隊(duì)列(ReferenceQueue)聯(lián)合使用腹备。當(dāng)垃 圾回收器準(zhǔn)備回收一個(gè)對象時(shí),如果發(fā)現(xiàn)它還有虛引用斤蔓,就會(huì)在回收對象的內(nèi)存之前植酥,把這個(gè)虛引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。程序可以通過判斷引用隊(duì)列中是 否已經(jīng)加入了虛引用弦牡,來了解被引用的對象是否將要被垃圾回收友驮。程序如果發(fā)現(xiàn)某個(gè)虛引用已經(jīng)被加入到引用隊(duì)列,那么就可以在所引用的對象的內(nèi)存被回收之前采取必要的行動(dòng)驾锰。

在實(shí)際開發(fā)中卸留,弱引用和虛引用不常用,用得比較多的是軟引用椭豫,因?yàn)樗梢约铀賘vm的回收耻瑟。

軟引用的使用方式:

關(guān)于軟引用,我之后會(huì)單獨(dú)寫一篇文章赏酥,所以這里先一筆帶過喳整。

對象的復(fù)制

java除了用new來創(chuàng)建對象,還可以通過clone來復(fù)制對象裸扶。

那么這兩種方式有什么相同和不同呢框都?

  • new

new操作符的本意是分配內(nèi)存。程序執(zhí)行到new操作符時(shí)呵晨,首先去看new操作符后面的類型魏保,因?yàn)橹懒祟愋驼崽#拍苤酪峙涠啻蟮膬?nèi)存空間。分配完內(nèi)存之后囱淋,再調(diào)用構(gòu)造函數(shù)猪杭,填充對象的各個(gè)域,這一步叫做對象的初始化妥衣,構(gòu)造方法返回后皂吮,一個(gè)對象創(chuàng)建完畢,可以把他的引用(地址)發(fā)布到外部税手,在外部就可以使用這個(gè)引用操縱這個(gè)對象蜂筹。

  • clone

clone在第一步是和new相似的, 都是分配內(nèi)存芦倒,調(diào)用clone方法時(shí)艺挪,分配的內(nèi)存和源對象(即調(diào)用clone方法的對象)相同,然后再使用原對象中對應(yīng)的各個(gè)域兵扬,填充新對象的域麻裳, 填充完成之后,clone方法返回器钟,一個(gè)新的相同的對象被創(chuàng)建津坑,同樣可以把這個(gè)新對象的引用發(fā)布到外部。

如何利用clone的方式來得到一個(gè)對象呢傲霸?

看代碼:

對Person類做了一些修改

看實(shí)現(xiàn)代碼:

這樣就得到了一個(gè)和原來一樣的新對象疆瑰。

深復(fù)制和淺復(fù)制

但是,細(xì)心并且善于思考的人可能一經(jīng)發(fā)現(xiàn)了一個(gè)問題昙啄。

age是一個(gè)基本數(shù)據(jù)類型穆役,支架clone沒什么問題,但是name可是一個(gè)String類型的啊梳凛。我們clone后的對象里的name和原來對象的name是不是指向同一個(gè)字符串常量呢耿币?

做個(gè)試驗(yàn):

果然,是同一個(gè)對象伶跷。如果你不能理解掰读,那么看這個(gè)圖。

其實(shí)如果只是String還好叭莫,因?yàn)镾tring的不可變性蹈集,當(dāng)你隨便修改一個(gè)值的時(shí)候,他們就會(huì)指向不同的地址了雇初,但是除了String拢肆,其他都是可變的。這就危險(xiǎn)了。

上面的這種情況郭怪,就是淺克隆支示。這種方式在你的屬性列表中有其他對象的引用的時(shí)候其實(shí)是很危險(xiǎn)的。所以鄙才,我們需要深克隆颂鸿。也就是說我們需要將這個(gè)對象里的對象也clone一份。怎么做呢攒庵?

在內(nèi)存中通過字節(jié)流的拷貝是比較容易實(shí)現(xiàn)的嘴纺。把母對象寫入到一個(gè)字節(jié)流中,再從字節(jié)流中將其讀出來浓冒,這樣就可以創(chuàng)建一個(gè)新的對象了栽渴,并且該新對象與母對象之間并不存在引用共享的問題,真正實(shí)現(xiàn)對象的深拷貝稳懒。

//使用該工具類的對象必須要實(shí)現(xiàn) Serializable 接口闲擦,否則是沒有辦法實(shí)現(xiàn)克隆的。
public class CloneUtils {

    public static <T extends Serializable> T clone(T   obj){
        T cloneObj = null;
        try {
            //寫入字節(jié)流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ObjectOutputStream obs = new   ObjectOutputStream(out);
            obs.writeObject(obj);
            obs.close();

            //分配內(nèi)存场梆,寫入原始對象墅冷,生成新對象
            ByteArrayInputStream ios = new  ByteArrayInputStream(out.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(ios);
            //返回生成的新對象
            cloneObj = (T) ois.readObject();
            ois.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cloneObj;
    }
}

使用該工具類的對象只要實(shí)現(xiàn) Serializable 接口就可實(shí)現(xiàn)對象的克隆,無須繼承 Cloneable 接口實(shí)現(xiàn) clone() 方法辙谜。

測試一下:

很完美

這個(gè)時(shí)候俺榆,Person類實(shí)現(xiàn)了Serializable接口

是否使用復(fù)制,深復(fù)制還是淺復(fù)制看情況來使用装哆。

關(guān)于序列化與反序列化以后會(huì)講。


這篇文章到這里就暫時(shí)告一段落了定嗓,后續(xù)有補(bǔ)充的話我會(huì)繼續(xù)補(bǔ)充蜕琴,有錯(cuò)誤的話,我也會(huì)及時(shí)改正宵溅。歡迎大家提出問題凌简。

示例代碼放在github:https://github.com/CleverFan/JavaImprove

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恃逻,隨后出現(xiàn)的幾起案子雏搂,更是在濱河造成了極大的恐慌,老刑警劉巖寇损,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凸郑,死亡現(xiàn)場離奇詭異,居然都是意外死亡矛市,警方通過查閱死者的電腦和手機(jī)芙沥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人而昨,你說我怎么就攤上這事救氯。” “怎么了歌憨?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵着憨,是天一觀的道長。 經(jīng)常有香客問我务嫡,道長甲抖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任植袍,我火速辦了婚禮惧眠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘于个。我一直安慰自己氛魁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布厅篓。 她就那樣靜靜地躺著秀存,像睡著了一般。 火紅的嫁衣襯著肌膚如雪羽氮。 梳的紋絲不亂的頭發(fā)上或链,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音档押,去河邊找鬼澳盐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛令宿,可吹牛的內(nèi)容都是我干的叼耙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼粒没,長吁一口氣:“原來是場噩夢啊……” “哼筛婉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起癞松,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤爽撒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后响蓉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體硕勿,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年厕妖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了首尼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挑庶。...
    茶點(diǎn)故事閱讀 38,064評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖软能,靈堂內(nèi)的尸體忽然破棺而出迎捺,到底是詐尸還是另有隱情,我是刑警寧澤查排,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布凳枝,位于F島的核電站,受9級特大地震影響跋核,放射性物質(zhì)發(fā)生泄漏岖瑰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一砂代、第九天 我趴在偏房一處隱蔽的房頂上張望蹋订。 院中可真熱鬧,春花似錦刻伊、人聲如沸露戒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽智什。三九已至,卻和暖如春丁屎,著一層夾襖步出監(jiān)牢的瞬間荠锭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工晨川, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留证九,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓共虑,卻偏偏與公主長得像甫贯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子看蚜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評論 2 345

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法赔桌,內(nèi)部類的語法供炎,繼承相關(guān)的語法,異常的語法疾党,線程的語...
    子非魚_t_閱讀 31,581評論 18 399
  • 前言 不知道大家有沒有這樣一種感覺雪位,程序員的數(shù)量井噴了竭钝。可能是因?yàn)榛ヂ?lián)網(wǎng)火了,也可能是各家培訓(xùn)機(jī)構(gòu)為我們拉來了大量...
    活這么大就沒飽過閱讀 2,713評論 6 26
  • (一)Java部分 1香罐、列舉出JAVA中6個(gè)比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,071評論 0 62
  • 6 主角來臨 爭吵起來后卧波,二人自然不歡而散了,望著漆黑一片的屏幕庇茫,蘇淼喘了幾口粗氣,冷道:“雨果,你是不是該出來了...
    余暉皆燼閱讀 343評論 5 9
  • 圖文/阿贊(原創(chuàng)) 生命中 總有那么多不經(jīng)意的相遇 讓你原本黑暗的生活 照進(jìn)來一束光 就像黑夜遇到晨光 就像枯木遇...
    劉小贊閱讀 521評論 0 1