真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Java編碼易疏忽哪些問題

本篇內(nèi)容介紹了“Java編碼易疏忽哪些問題”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

創(chuàng)新互聯(lián)專注于瀾滄網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供瀾滄營銷型網(wǎng)站建設(shè),瀾滄網(wǎng)站制作、瀾滄網(wǎng)頁設(shè)計、瀾滄網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造瀾滄網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供瀾滄網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。

1.糾結(jié)的同名

現(xiàn)象

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

解決

寫完代碼時,掃視下import部分,看看有沒有不熟悉的。替換成正確導(dǎo)入后,要注意下注釋是否也作相應(yīng)修改。

啟示

命名盡量避開重復(fù)名,特別要避開與JDK中的類重名,否則容易導(dǎo)入錯,同時存在大量重名類,在查找時,也需要更多的辨別時間。

2.想當然的API

現(xiàn)象

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

示例一:flag是true?

雙擊代碼全選

1

booleanflag=Boolean.getBoolean("true");

可能老是false。

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

Calendarcalendar=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)象

有時候溢出并不難,雖然不常復(fù)現(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,于是下面代碼結(jié)果小于0,也是因為溢出導(dǎo)致:

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都打了,怎么找不到?

示例一:沒有stacktrace!

}catch(Exceptionex){

log.error(ex);

}

示例二:找不到log!

}catch(ConfigurationExceptione){

e.printStackTrace();

}

解決

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

換成普通的log4j吧,而不是System.out。

啟示

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

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

5.遺忘的volatile

現(xiàn)象

在DCL模式中,總是忘記加一個Volatile。

privatestaticCacheImplinstance;//losevolatile

publicstaticCacheImplgetInstance(){

if(instance==null){

synchronized(CacheImpl.class){

if(instance==null){

instance=newCacheImpl();

}

}

}

returninstance;

}

解決

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

啟示

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

Java編碼易疏忽哪些問題

6.不要影響彼此

現(xiàn)象

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

publicstaticvoidinputToOutput(InputStreamis,OutputStreamos,

booleanisClose)throwsIOException{

BufferedInputStreambis=newBufferedInputStream(is,1024);

BufferedOutputStreambos=newBufferedOutputStream(os,1024);

….

if(isClose){

bos.close();

bis.close();

}

}

假設(shè)bos關(guān)閉失敗,bis還能關(guān)閉嗎?當然不能!

解決辦法

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

啟示

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

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

現(xiàn)象

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

privatevoidsend(ListeventList){

asserteventList!=null;

}

解決

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

啟示

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

8.用戶認知負擔(dān)有時候很重

現(xiàn)象

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

示例一:

publicvoidcaller(inta,Stringb,floatc,Stringd){

methodOne(d,z,b);

methodTwo(b,c,d);

}

publicvoidmethodOne(Stringd,floatz,Stringb)

publicvoidmethodTwo(Stringb,floatc,Stringd)

示例二:

雙擊代碼全選

1

2

3

4

publicbooleanremove(Stringkey,longtimeout){

Futurefuture=memcachedClient.delete(key);

publicbooleandelete(Stringkey,longtimeout){

Futurefuture=memcachedClient.delete(key);

示例三:

雙擊代碼全選

1

2

publicstaticStringgetDigest(StringfilePath,DigestAlgorithmalgorithm)

publicstaticStringgetDigest(StringfilePath,DigestAlgorithmdigestAlgorithm)

解決

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

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

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

啟示

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

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

現(xiàn)象

存在下面兩則示例:

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

雙擊代碼全選

1

2

3

4

5

catch(SocketExceptione)

{

LOG.error("servererror",e);

thrownewConnectionException(e.getMessage(),e);

}

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

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

雙擊代碼全選

1

LOG.warn("Failedtologinby"+username+");

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

如果惡意登錄,那系統(tǒng)內(nèi)部會出現(xiàn)太多WARN,從而讓管理員誤以為是代碼錯誤??梢苑答佊脩粢藻e誤,但是不要記錄用戶錯誤的行為,除非想達到控制的目的。

啟示

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

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

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

10.忘設(shè)初始容量

現(xiàn)象

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

雙擊代碼全選

1

cache=newLRULinkedHashMap(maxCapacity);

解決

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

“Java編碼易疏忽哪些問題”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!


分享名稱:Java編碼易疏忽哪些問題
URL網(wǎng)址:http://weahome.cn/article/ihiojs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部