日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

N个Java开发常用规范技巧总结

發(fā)布時間:2024/4/11 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 N个Java开发常用规范技巧总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

點擊上方“朱小廝的博客”,選擇“設(shè)為星標(biāo)

做積極的人,而不是積極廢人



1、類的命名使用駝峰式命名的規(guī)范。

例如:UserService,但是以下情景例外:DO / BO / PO / DTO / VO。

例如說:UserPO,StudentPO(PO,VO,DTO,等這類名詞需要全大寫)

@Data@Builderpublic?class?CustomBodyDTO?{????private?String?name;????private?String?idCode;????private?String?status;}

2、如果在模塊或者接口,類,方法中使用了設(shè)計模式,那么請在命名的時候體現(xiàn)出來。

例如說:TokenFactory,LoginProxy等。

public?class?TokenFactory?{????public?TokenDTO?buildToken(LoginInfo?loginInfo)?{????????String?token?=?UUID.randomUUID().toString();????????TokenDTO?tokenDTO?=?TokenDTO.builder()????????????????.token(token)????????????????.createTime(LocalDateTime.now())????????????????.build();????????String?redisKey?=?RedisKeyBuilder.buildTokenKey(token);????????redisService.setObject(redisKey,?loginInfo,?Timeout.ONE_DAY?*?30?*?2);????????log.info("創(chuàng)建token成功|loginInfo={}",?loginInfo.toString());????????return?tokenDTO;????}}

3、Object 的 equals 方法容易拋空指針異常。

從源碼來進行分析equals方法是屬于Object類的,如果調(diào)用方為null,那么自然在運行的時候會拋出空指針異常的情況。

object類中的源碼:

????public?boolean?equals(Object?obj)?{????????return?(this?==?obj);????}

為了避免這種現(xiàn)況出現(xiàn),在比對的時候盡量將常量或者有確定值的對象置前。

例如說:

正確:“test”.equals(object);錯誤:object.equals(“test”);

4、對于所有相同類型的包裝類進行比較的時候,都是用equal來進行操作。

對于Integer類來說,當(dāng)相應(yīng)的變量數(shù)值范圍在-128到127之間的時候,該對象會被存儲在IntegerCache.cache里面,因此會有對象復(fù)用的情況發(fā)生。

所以對于包裝類進行比較的時候,最好統(tǒng)一使用equal方法。

????private?static?class?IntegerCache?{????????static?final?int?low?=?-128;????????static?final?int?high;????????static?final?Integer?cache[];????????static?{????????????//?high?value?may?be?configured?by?property????????????int?h?=?127;????????????String?integerCacheHighPropValue?=????????????????sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");????????????if?(integerCacheHighPropValue?!=?null)?{????????????????try?{????????????????????int?i?=?parseInt(integerCacheHighPropValue);????????????????????i?=?Math.max(i,?127);????????????????????//?Maximum?array?size?is?Integer.MAX_VALUE????????????????????h?=?Math.min(i,?Integer.MAX_VALUE?-?(-low)?-1);????????????????}?catch(?NumberFormatException?nfe)?{????????????????????//?If?the?property?cannot?be?parsed?into?an?int,?ignore?it.????????????????}????????????}????????????high?=?h;????????????cache?=?new?Integer[(high?-?low)?+?1];????????????int?j?=?low;????????????for(int?k?=?0;?k?<?cache.length;?k++)????????????????cache[k]?=?new?Integer(j++);????????????//?range?[-128,?127]?must?be?interned?(JLS7?5.1.7)????????????assert?IntegerCache.high?>=?127;????????}????????private?IntegerCache()?{}????}??public?static?Integer?valueOf(int?i)?{????????if?(i?>=?IntegerCache.low?&&?i?<=?IntegerCache.high)????????????return?IntegerCache.cache[i?+?(-IntegerCache.low)];????????return?new?Integer(i);????}

5、所有的pojo類中的屬性最好統(tǒng)一使用包裝類屬性類型數(shù)據(jù)。RPC方法的返回值和參數(shù)都統(tǒng)一使用包裝類數(shù)據(jù)。局部變量中使用基本的數(shù)據(jù)類型。

對于實際的應(yīng)用場景來說,例如說一個學(xué)生類,當(dāng)我們設(shè)置里面的成績字段為int類型的時候,如果學(xué)生沒有考試,那么這個成績字段應(yīng)該為空,但是int默認(rèn)會賦值為0,那么這個時候使用基本數(shù)據(jù)類型就容易產(chǎn)生誤區(qū),到底是考了0分,還是說沒有參加考試。

如果換成使用包裝類Integer類型的話,就可以通過null值來進行區(qū)分了。

6、當(dāng)pojo類在進行編寫的時候要重寫相應(yīng)的toString方法,如果該pojo中繼承了另外的一個pojo類,那么請在相應(yīng)的tostring函數(shù)中加入super.toString()方法。

通過重寫toString方法有利于在日志輸出的時候查看相應(yīng)對象的屬性內(nèi)容進行逐一分析,對于一些有繼承關(guān)系的對象而言,加入了super.toString方法更加有助于對該對象的理解和分析。

7、在pojo的getter和setter方法里面,不要增加業(yè)務(wù)邏輯的代碼編寫,這樣會增加問題排查的難度。

正確做法:


public?class?User?{????private?Integer?id;????private?String?username;????public?Integer?getId()?{????????return?id;????}????public?User?setId(Integer?id)?{????????this.id?=?id;????????return?this;????}????public?String?getUsername()?{????????return?username;????}????public?User?setUsername(String?username)?{????????this.username?=?username;????????return?this;????}} public?class?User?{????private?Integer?id;????private?String?username;????public?Integer?getId()?{????????return?id;????}????public?User?setId(Integer?id)?{????????this.id?=?id;????????return?this;????}????public?String?getUsername()?{????????return?"key-prefix-"+username;????}????public?User?setUsername(String?username)?{????????this.username?=?"key-prefix-"+username;????????return?this;????}}

8、final 可以聲明類、成員變量、方法、以及本地變量。

下列情況使用 final 關(guān)鍵字:

  • 不允許被繼承的類,如:String 類。

  • 不允許修改引用的域?qū)ο?#xff0c;如:POJO 類的域變量。

  • 不允許被重寫的方法,如:POJO 類的 setter 方法。

  • 不允許運行過程中重新賦值的局部變量。

  • 避免上下文重復(fù)使用一個變量,使用 final 描述可以強制重新定義一個變量,方便更好地進行重構(gòu)。

9、對于任何類而言,只要重寫了equals就必須重寫hashcode。

舉例說明:

1)HashSet在存儲數(shù)據(jù)的時候是存儲不重復(fù)對象的,這些對象在進行判斷的時候需要依賴hashcode和equals方法,因此需要重寫。

2)在自定義對象作為key鍵時,需要重寫hashcode和equals方法,例如說String類就比較適合用于做key來使用。

10、不要在 foreach 循環(huán)里進行元素的 remove/add 操作。

remove 元素請使用 Iterator方式,如果并發(fā)操作,需要對 Iterator 對象加鎖。

Iterator<String>?iterator?=?list.iterator();while?(iterator.hasNext())?{String?item?=?iterator.next();if?(刪除元素的條件)?{iterator.remove();}}

11、使用HashMap的時候,可以指定集合的初始化大小。

例如說,HashMap里面需要存放10000個元素,但是由于沒有進行初始化大小操作,所以在添加元素的時候,hashmap的內(nèi)部會一直在進行擴容操作,影響性能。

那么為了減少擴容操作,可以在初始化的時候?qū)ashmap的大小設(shè)置為:已知需要存儲的大小/負(fù)載因子(0.75)+1

???HashMap?hashMap=new?HashMap<>(13334);

12、Map類集合中,K/V對于null類型存儲的情況:

集合名稱keyvalue說明
HashMap允許為null允許為null線程不安全
TreeMap不允許為null允許為null線程不安全
HashTable不允許為null不允許為null線程安全
ConcurrentHashMap不允許為null不允許為null線程安全

13、可以利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作,避免使用 List 的contains 方法進行遍歷、對比、去重操作。

通關(guān)觀察可以發(fā)現(xiàn),HashSet底層通過將傳入的值再傳入到一個HashMap里面去進行操作,進入到HashMap里面之后,會先通過調(diào)用該對象的hashcode來判斷是否有重復(fù)的值,如果有再進行equals判斷,如果沒有相同元素則插入處理。

???public?boolean?add(E?e)?{????????return?map.put(e,?PRESENT)==null;????}

14、線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學(xué)更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風(fēng)險。

錯誤做法:

ExecutorService?executors?=?Executors.newSingleThreadExecutor();ScheduledExecutorService?scheduledExecutorService?=?Executors.newScheduledThreadPool(5);

對于線程池的參數(shù)需要有深入的理解后,結(jié)合實際的機器參數(shù)來進行參數(shù)設(shè)置,從而防止在使用中出現(xiàn)異常。

????ExecutorService?fixedExecutorService?=?new?ThreadPoolExecutor(????????????????1,????????????????2,?????????????????60,????????????????TimeUnit.SECONDS,?????????????????linkedBlockingQueue,?????????????????new?MyThreadFactory(),????????????????new?ThreadPoolExecutor.AbortPolicy()????????);

ps:使用Executors.new方式創(chuàng)建線程池的缺點:

對于FixedThreadPool 和 SingleThreadPool而言

允許的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求,從而導(dǎo)致 OOM。

對于CachedThreadPool 和 ScheduledThreadPool而言

允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE,可能會創(chuàng)建大量的線程,從而導(dǎo)致 OOM。

15、使用一些日期類的時候,推薦使用LocalDateTime來替代Calendar類,或者說使用Instant來替代掉Date類。

16、盡量避免在for循環(huán)里面執(zhí)行try-catch操作,可以選擇將try-catch操作放在循環(huán)體外部使用。

?正確做法:


try?{?????????for?(int?i?=?0;?i?<?100;?i++)?{?????????????doSomeThing();???????? }???????}catch?(Exception?e){????????????e.printStackTrace();???????} for?(int?i?=?0;?i?<?100;?i++)?{ try?{????????????????doSomeThing();????????????}?catch?(Exception?e)?{????????????????e.printStackTrace();????????????}????????}

17、對于大段的代碼進行try-catch操作,這是一種不負(fù)責(zé)任的行為,將穩(wěn)定的代碼也都包圍在了try-catch語句塊里面沒能很好的分清代碼的穩(wěn)定性范圍。

通常我們稱在運行中不會出錯的代碼塊為穩(wěn)定性代碼,可能會有異常出錯的部分為非穩(wěn)定性代碼塊,后者才是try-catch重點需要關(guān)注的對象。

18、在jdk7之后,對于流這類需要關(guān)閉連接釋放資源的對象,可以使用try-with-resource處理機制來應(yīng)對。

例如下方代碼:

??File?file?=?new?File("*****");????????try?(FileInputStream?fin?=?new?FileInputStream(file))?{????????????//執(zhí)行相關(guān)操作????????}?catch?(Exception?e)?{????????????//異常捕獲操作????????}

19、使用ArrayList的時候,如果清楚它的指定大小的話,可以盡量在初始化的時候進行大小指定,因為隨著arraylist不斷添加新的元素之后,鏈表的體積會不斷增大擴容。

????private?void?grow(int?minCapacity)?{????????//?overflow-conscious?code????????int?oldCapacity?=?elementData.length;????????int?newCapacity?=?oldCapacity?+?(oldCapacity?>>?1);????????if?(newCapacity?-?minCapacity?<?0)????????????newCapacity?=?minCapacity;????????if?(newCapacity?-?MAX_ARRAY_SIZE?>?0)????????????newCapacity?=?hugeCapacity(minCapacity);????????//?minCapacity?is?usually?close?to?size,?so?this?is?a?win:????????elementData?=?Arrays.copyOf(elementData,?newCapacity);????}

20、對于一些短信,郵件,電話,下單,支付等應(yīng)用場景而言,開發(fā)的時候需要設(shè)置相關(guān)的防重復(fù)功能限制,防止出現(xiàn)某些惡意刷單,濫刷這類型情況。

21、對于敏感詞匯發(fā)表的時候,需要考慮一些文本過濾的策略。

這一塊的功能可以考慮直接接入市面上已有的成熟的UGC監(jiān)控服務(wù),或者使用公司內(nèi)部自研的ugc過濾工具,防止用戶發(fā)表惡意評論等情況出現(xiàn)。

22、在建立索引的時候,對于索引的命名需要遵循一定的規(guī)范:

索引類型命名規(guī)則案例
主鍵索引pk_字段名,pk是指primary keypk_order_id
唯一索引uk_字段名,uk是指 unique keyuk_order_id
普通索引idx_字段名,idx是指 indexidx_order_id

23、當(dāng)我們需要存儲一段文本信息的時候,需要先考慮存儲文本的長度。

如果文本的長度超過了5000,則不建議再選擇使用varchar類型來進行存儲,可以考慮使用text類型進行數(shù)據(jù)存儲,這個時候可以考慮單獨用一張表來進行存儲數(shù)據(jù),并且通過一個額外的主鍵id來對應(yīng),從而避免影響其他字段的查詢。

24、在進行數(shù)據(jù)庫命名的時候盡量保證數(shù)據(jù)庫的名稱和項目工程的名稱一致。

25、在進行表結(jié)構(gòu)設(shè)計的時候,只要具有唯一性質(zhì)的字段都需要建立唯一索引。

這樣有助于后期進行查詢的時候提高查詢的效率,沒有唯一索引這一層的保障,即使在業(yè)務(wù)層加入了攔截,但是依然容易造成線上臟數(shù)據(jù)的產(chǎn)生。

26、在進行order by這類型sql查詢的時候,需要注意查詢索引的有序性。

關(guān)于索引的建立,可以去了解一下索引的星級評定,例如三星索引。但是個人認(rèn)為索引沒有所謂的最優(yōu)性,需要結(jié)合實際的業(yè)務(wù)場景來設(shè)計。

27、在MySQL中,使用count(*)會統(tǒng)計值為 NULL 的行,而 count(列名)不會統(tǒng)計此列為 NULL 值的行。

28、在進行數(shù)據(jù)庫存儲引擎選擇的時候,需要結(jié)合相關(guān)的應(yīng)用場景來選擇,如果是需要應(yīng)用在select操作較多的情況下,可以選擇使用MyIsAM存儲引擎,如果是對于數(shù)據(jù)的insert,update,這類修改操作較多的業(yè)務(wù)場景,則優(yōu)先推薦使用innodb存儲引擎。目前普遍互聯(lián)網(wǎng)公司都推薦使用innodb較多。



想知道更多?
描下面的二維碼關(guān)注我

好文推薦:

  • 基于數(shù)據(jù)庫實現(xiàn)的分布式鎖

  • 基于Redis實現(xiàn)的分布式鎖

  • 為了追求極致的性能,Kafka掌控了這11項要領(lǐng)


>>>Learn More<<


喜歡就點個"在看"唄^_^

超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的N个Java开发常用规范技巧总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。