Java編程中最容易忽略的10個問題颁褂。

給你Java學習路線:html-css-js-jq-javase-數(shù)據(jù)庫-jsp-servlet-Struts2-hibernate-mybatis-spring4-springmvc-ssh-ssm

在Java編碼中财岔,我們?nèi)菀追敢恍╁e誤同规,也容易疏忽一些問題盯孙,因此筆者對日常編碼中曾遇到的一些經(jīng)典情形歸納整理成文,以共同探討宫患。

1. 糾結的同名

現(xiàn)象

很多類的命名相同(例如:常見于異常、常量铐伴、日志等類)撮奏,導致在import時,有時候張冠李戴当宴,這種錯誤有時候很隱蔽畜吊。因為往往同名的類功能也類似,所以IDE不會提示warn户矢。

解決

寫完代碼時玲献,掃視下import部分,看看有沒有不熟悉的。替換成正確導入后捌年,要注意下注釋是否也作相應修改瓢娜。

啟示

命名盡量避開重復名,特別要避開與JDK中的類重名礼预,否則容易導入錯眠砾,同時存在大量重名類,在查找時托酸,也需要更多的辨別時間褒颈。

小編推薦一個學Java的學習裙【 六五零,五五四励堡,六零七 】谷丸,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習应结!裙內(nèi)有開發(fā)工具刨疼,很多干貨和技術資料分享!

2. 想當然的API

現(xiàn)象

有時候調(diào)用API時鹅龄,會想當然的通過名字直接自信滿滿地調(diào)用揩慕,導致很驚訝的一些錯誤:

示例一:flag是true?

booleanflag = Boolean.getBoolean("true");

可能老是false砾层。

示例二:這是去年的今天嗎(今年是2012年漩绵,不考慮閏年)?結果還是2012年:

Calendar calendar = GregorianCalendar.getInstance();

calendar.roll(Calendar.DAY_OF_YEAR, -365);

下面的才是去年:

calendar.add(Calendar.DAY_OF_YEAR,-365);

解決辦法

問自己幾個問題肛炮,這個方法我很熟悉嗎止吐?有沒有類似的API? 區(qū)別是什么?就示例一而言侨糟,需要區(qū)別的如下:

Boolean.valueOf(b)VSBoolean.parseBoolean(b)VSBoolean.getBoolean(b);

啟示

名字起的更詳細點碍扔,注釋更清楚點,不要不經(jīng)了解秕重、測試就想當然的用一些API不同,如果時間有限,用自己最為熟悉的API溶耘。

3. 有時候溢出并不難

現(xiàn)象

有時候溢出并不難二拐,雖然不常復現(xiàn):

示例一:

longx=Integer.MAX_VALUE+1;System.out.println(x);

x是多少?竟然是-2147483648凳兵,明明加上1之后還是long的范圍百新。類似的經(jīng)常出現(xiàn)在時間計算:

數(shù)字1×數(shù)字2×數(shù)字3…

示例二:

在檢查是否為正數(shù)的參數(shù)校驗中,為了避免重載庐扫,選用參數(shù)number, 于是下面代碼結果小于0饭望,也是因為溢出導致:

Numberi=Long.MAX_VALUE;System.out.println(i.intValue()>0);

解決

讓第一個操作數(shù)是long型仗哨,例如加上L或者l(不建議小寫字母l,因為和數(shù)字1太相似了)铅辞;

不確定時厌漂,還是使用重載吧,即使用doubleValue()斟珊,當參數(shù)是BigDecimal參數(shù)時苇倡,也不能解決問題。

啟示

對數(shù)字運用要保持敏感:涉及數(shù)字計算就要考慮溢出囤踩;涉及除法就要考慮被除數(shù)是0雏节;實在容納不下了可以考慮BigDecimal之類。

4. 日志跑哪了高职?

現(xiàn)象

有時候覺得log都打了,怎么找不到辞州?

示例一:沒有stack trace怔锌!

}catch(Exceptionex) { ? ?log.error(ex); }

示例二:找不到log!

}catch(ConfigurationExceptione) { ? ?e.printStackTrace();}

解決

替換成log.error(ex.getMessage(),ex);

換成普通的log4j吧变过,而不是System.out埃元。

啟示

API定義應該避免讓人犯錯,如果多加個重載的log.error(Exception)自然沒有錯誤發(fā)生

在產(chǎn)品代碼中媚狰,使用的一些方法要考慮是否有效岛杀,使用e.printStackTrace()要想下終端(Console)在哪。

5. 遺忘的Volatile

現(xiàn)象

在DCL模式中崭孤,總是忘記加一個Volatile类嗤。

privatestaticCacheImpl instance;//lose volatilepublicstaticCacheImplgetInstance(){if(instance ==null) {synchronized(CacheImpl.class) {if(instance ==null) { ? ? ? ? ? ? ? ?instance =newCacheImpl ();? ? ? ? ? ? ?} ? ? ? ?} ? ?}returninstance;}

解決

毋庸置疑,加上一個吧辨宠,synchronized 鎖的是一塊代碼(整個方法或某個代碼塊)遗锣,保證的是這”塊“代碼的可見性及原子性,但是instance == null第一次判斷時不再范圍內(nèi)的嗤形。所以可能讀出的是過期的null精偿。

啟示

我們總是覺得某些低概率的事件很難發(fā)生,例如某個時間并發(fā)的可能性赋兵、某個異常拋出的可能性笔咽,所以不加控制,但是如果可以霹期,還是按照前人的“最佳實踐”來寫代碼吧叶组。至少不用過多解釋為啥另辟蹊徑。

小編推薦一個學Java的學習裙【 六五零经伙,五五四扶叉,六零七 】勿锅,無論你是大牛還是小白,是想轉行還是想入行都可以來了解一起進步一起學習枣氧!裙內(nèi)有開發(fā)工具溢十,很多干貨和技術資料分享!

6. 不要影響彼此

現(xiàn)象

在釋放多個IO資源時达吞,都會拋出IOException 张弛,于是可能為了省事如此寫:

publicstaticvoidinputToOutput(InputStream is, OutputStream os,booleanisClose)throwsIOException { ? ?BufferedInputStream bis =newBufferedInputStream(is,1024); ? ?BufferedOutputStream bos =newBufferedOutputStream(os,1024); ? ? ?….if(isClose) { ? ? ? bos.close(); ? ? ? bis.close(); ? ?}}

假設bos關閉失敗,bis還能關閉嗎酪劫?當然不能吞鸭!

解決辦法

雖然拋出的是同一個異常,但是還是各自捕獲各的為好覆糟。否則第一個失敗刻剥,后一個面就沒有機會去釋放資源了。

啟示

代碼/模塊之間可能存在依賴滩字,要充分識別對相互的依賴造虏。

7. 用斷言取代參數(shù)校驗

現(xiàn)象

如題所提,作為防御式編程常用的方式:斷言麦箍,寫在產(chǎn)品代碼中做參數(shù)校驗等漓藕。例如:

privatevoidsend(List< Event> eventList){asserteventList !=null;}

解決

換成正常的統(tǒng)一的參數(shù)校驗方法。因為斷言默認是關閉的挟裂,所以起不起作用完全在于配置享钞,如果采用默認配置,經(jīng)歷了eventList != null結果還沒有起到作用诀蓉,徒勞無功栗竖。

啟示

有的時候,代碼起不起作用交排,不僅在于用例划滋,還在于配置,例如斷言是否啟用埃篓、log級別等处坪,要結合真實環(huán)境做有用編碼。

8. 用戶認知負擔有時候很重

現(xiàn)象

先來比較三組例子架专,看看那些看著更順暢同窘?

示例一:

publicvoidcaller(inta, String b,floatc, String d){ ? ?methodOne(d, z, b); ? ?methodTwo(b, c, d);}publicvoidmethodOne(String d,floatz, String b)publicvoidmethodTwo(String b,floatc, String d)

示例二:

publicbooleanremove(String key,longtimeout){ ? ? ? ? ? ? Future< Boolean> future = memcachedClient.delete(key);publicbooleandelete(String key,longtimeout){ ? ? ? ? ? ? Future< Boolean> future = memcachedClient.delete(key);

示例三:

publicstaticStringgetDigest(StringfilePath, DigestAlgorithm algorithm)publicstaticStringgetDigest(StringfilePath, DigestAlgorithm digestAlgorithm)

解決

保持參數(shù)傳遞順序;

remove變成了delete部脚,顯得突兀了點想邦, 統(tǒng)一表達更好;

保持表達委刘,少縮寫也會看起來流暢點丧没。

啟示

在編碼過程中鹰椒,不管是參數(shù)的順序還是命名都盡量統(tǒng)一,這樣用戶的認知負擔會很少呕童,不要要用戶容易犯錯或迷惑漆际。例如用枚舉代替string從而不讓用戶迷惑到底傳什么string, 諸如此類。

9. 忽視日志記錄時機夺饲、級別

現(xiàn)象

存在下面兩則示例:

示例一:該不該記錄日志奸汇?

catch(SocketException e){ ? ?LOG.error("server error", e);thrownewConnectionException(e.getMessage(), e);}

示例二:記什么級別日志?

在用戶登錄系統(tǒng)中往声,每次失敗登錄:

LOG.warn("Failed to login by "+username+");

解決

移除日志記錄:在遇到需要re-throw的異常時擂找,如果每個人都按照先記錄后throw的方式去處理,那么對一個錯誤會記錄太多的日志浩销,所以不推薦如此做贯涎;但是如果re-throw出去的exception沒有帶完整的trace( 即cause),那么最好還是記錄下慢洋。

如果惡意登錄柬采,那系統(tǒng)內(nèi)部會出現(xiàn)太多WARN,從而讓管理員誤以為是代碼錯誤且警。可以反饋用戶以錯誤礁遣,但是不要記錄用戶錯誤的行為斑芜,除非想達到控制的目的。

啟示

日志改不改記祟霍?記成什么級別杏头?如何記?這些都是問題沸呐,一定要根據(jù)具體情況醇王,需要考慮:

是用戶行為錯誤還是代碼錯誤?

記錄下來的日志崭添,能否能給別人在不造成過多的干擾前提下提供有用的信息以快速定位問題寓娩。

10. 忘設初始容量

現(xiàn)象

在JAVA中,我們常用Collection中的Map做Cache,但是我們經(jīng)常會遺忘設置初始容量呼渣。

cache=newLRULinkedHashMap< K, V>(maxCapacity);

解決

初始容量的影響有多大棘伴?拿LinkedHashMap來說,初始容量如果不設置默認是16屁置,超過16×LOAD_FACTOR,會resize(2 * table.length),擴大2倍:采用 Entry[] newTable = new Entry[newCapacity]; transfer(newTable)焊夸,即整個數(shù)組Copy, 那么對于一個需要做大容量CACHE來說蓝角,從16變成一個很大的數(shù)量阱穗,需要做多少次數(shù)組復制可想而知饭冬。如果初始容量就設置很大,自然會減少resize, 不過可能會擔心揪阶,初始容量設置很大時昌抠,沒有Cache內(nèi)容仍然會占用過大體積。其實可以參考以下表格簡單計算下, 初始時還沒有cache內(nèi)容, 每個對象僅僅是4字節(jié)引用而已遣钳。

memory for reference fields (4 bytes each);

memory for primitive fields

Java typeBytes required

boolean1

byte

char2

short

int4

float

long8

double

啟示:小編推薦一個學Java的學習裙【 六五零扰魂,五五四,六零七 】蕴茴,無論你是大牛還是小白劝评,是想轉行還是想入行都可以來了解一起進步一起學習!裙內(nèi)有開發(fā)工具倦淀,很多干貨和技術資料分享蒋畜!

不僅是map, 還有stringBuffer等,都有容量resize的過程撞叽,如果數(shù)據(jù)量很大姻成,就不能忽視初始容量可以考慮設置下,否則不僅有頻繁的 resize還容易浪費容量愿棋。

在Java編程中科展,除了上面枚舉的一些容易忽視的問題,日常實踐中還存在很多糠雨。相信通過不斷的總結和努力才睹,可以將我們的程序完美呈現(xiàn)給讀者。

Java是一種可以撰寫跨平臺應用軟件的面向對象的程序設計語言甘邀。Java 技術具有卓越的通用性琅攘、高效性、平臺移植性和安全性松邪,廣泛應用于PC坞琴、數(shù)據(jù)中心、游戲控制臺逗抑、科學超級計算機剧辐、移動電話和互聯(lián)網(wǎng),同時擁有全球最大的開發(fā)者專業(yè)社群邮府。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泉粉,一起剝皮案震驚了整個濱河市愿卒,隨后出現(xiàn)的幾起案子徒坡,更是在濱河造成了極大的恐慌状土,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊服,死亡現(xiàn)場離奇詭異檀轨,居然都是意外死亡胸竞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門参萄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來卫枝,“玉大人,你說我怎么就攤上這事讹挎⌒3啵” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵筒溃,是天一觀的道長马篮。 經(jīng)常有香客問我,道長怜奖,這世上最難降的妖魔是什么浑测? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮歪玲,結果婚禮上迁央,老公的妹妹穿的比我還像新娘。我一直安慰自己滥崩,他們只是感情好岖圈,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著钙皮,像睡著了一般幅狮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上株灸,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音擎值,去河邊找鬼慌烧。 笑死,一個胖子當著我的面吹牛鸠儿,可吹牛的內(nèi)容都是我干的屹蚊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼进每,長吁一口氣:“原來是場噩夢啊……” “哼汹粤!你這毒婦竟也來了?” 一聲冷哼從身側響起田晚,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘱兼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后贤徒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芹壕,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡汇四,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了踢涌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片通孽。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖睁壁,靈堂內(nèi)的尸體忽然破棺而出背苦,到底是詐尸還是另有隱情,我是刑警寧澤潘明,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布行剂,位于F島的核電站,受9級特大地震影響钉疫,放射性物質發(fā)生泄漏硼讽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一牲阁、第九天 我趴在偏房一處隱蔽的房頂上張望固阁。 院中可真熱鬧,春花似錦城菊、人聲如沸备燃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并齐。三九已至,卻和暖如春客税,著一層夾襖步出監(jiān)牢的瞬間况褪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工更耻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留测垛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓秧均,卻偏偏與公主長得像食侮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子目胡,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理锯七,服務發(fā)現(xiàn),斷路器誉己,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 在社交網(wǎng)絡中,我們看到了太多太多人的生活是如何的美好效五,卻忘記了放下手機地消,放下羨慕,努力讓自己的生活也美好畏妖。我們生活...
    Thorn紙閱讀 350評論 0 0
  • 參考書目:《刻意練習》[美] 安德斯·艾利克森 / 羅伯特·普爾 這些年脉执,一直在原地徘徊,看見人來看到人往戒劫。四周望...
    安心悅舍閱讀 460評論 2 3
  • 家里事多不回去不好半夷,而且要接孩子,和先生分別請假周五就一起回老家迅细。而且在我自己的堅持下巫橄,終于迎來了我第一次駕駛高速...
    自己在這里閱讀 228評論 0 3
  • 年關將至,天氣也愈發(fā)寒冷茵典。依悠也盼著這年的雪快些落下才好湘换。因為每年初雪,霍軒都會帶著依悠去賞雪景统阿。也可見得霍軒是多...
    無巽閱讀 248評論 0 0