您好,登錄后才能下訂單哦!
本篇內容主要講解“Java開發常用規范技巧有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Java開發常用規范技巧有哪些”吧!
1、Object 的 equals 方法容易拋空指針異常。
從源碼來進行分析equals方法是屬于Object類的,如果調用方為null,那么自然在運行的時候會拋出空指針異常的情況。
object類中的源碼:
從源碼來進行分析equals方法是屬于Object類的,如果調用方為null,那么自然在運行的時候會拋出空指針異常的情況。
object類中的源碼:
public boolean equals(Object obj) {
return (this == obj);
}
為了避免這種現況出現,在比對的時候盡量將常量或者有確定值的對象置前。
例如說:
正確:“test”.equals(object);
錯誤:object.equals(“test”);
2、類的命名使用駝峰式命名的規范。
例如:UserService,但是以下情景例外:DO / BO / PO / DTO / VO。
例如說:UserPO,StudentPO(PO,VO,DTO,等這類名詞需要全大寫)
@Data
@Builder
public class CustomBodyDTO {
private String name;
private String idCode;
private String status;
}
如果在模塊或者接口,類,方法中使用了設計模式,那么請在命名的時候體現出來。例如說: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("創建token成功|loginInfo={}", loginInfo.toString());
return tokenDTO;
}
}
4、對于所有相同類型的包裝類進行比較的時候,都是用equal來進行操作。
對于Integer類來說,當相應的變量數值范圍在-128到127之間的時候,該對象會被存儲在IntegerCache.cache里面,因此會有對象復用的情況發生。
所以對于包裝類進行比較的時候,最好統一使用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類中的屬性最好統一使用包裝類屬性類型數據。RPC方法的返回值和參數都統一使用包裝類數據。局部變量中使用基本的數據類型。
對于實際的應用場景來說,例如說一個學生類,當我們設置里面的成績字段為int類型的時候,如果學生沒有考試,那么這個成績字段應該為空,但是int默認會賦值為0,那么這個時候使用基本數據類型就容易產生誤區,到底是考了0分,還是說沒有參加考試。
如果換成使用包裝類Integer類型的話,就可以通過null值來進行區分了。
6、當pojo類在進行編寫的時候要重寫相應的toString方法,如果該pojo中繼承了另外的一個pojo類,那么請在相應的tostring函數中加入super.toString()方法。
通過重寫toString方法有利于在日志輸出的時候查看相應對象的屬性內容進行逐一分析,對于一些有繼承關系的對象而言,加入了super.toString方法更加有助于對該對象的理解和分析。
7、在pojo的getter和setter方法里面,不要增加業務邏輯的代碼編寫,這樣會增加問題排查的難度。
正確做法:
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;
}
}
8、final 可以聲明類、成員變量、方法、以及本地變量。
下列情況使用 final 關鍵字:
不允許被繼承的類,如:String 類。
不允許修改引用的域對象,如:POJO 類的域變量。
不允許被重寫的方法,如:POJO 類的 setter 方法。
不允許運行過程中重新賦值的局部變量。
避免上下文重復使用一個變量,使用 final 描述可以強制重新定義一個變量,方便更好地進行重構。
9、對于任何類而言,只要重寫了equals就必須重寫hashcode。
舉例說明:
1)HashSet在存儲數據的時候是存儲不重復對象的,這些對象在進行判斷的時候需要依賴hashcode和equals方法,因此需要重寫。
2)在自定義對象作為key鍵時,需要重寫hashcode和equals方法,例如說String類就比較適合用于做key來使用。
10、不要在 foreach 循環里進行元素的 remove/add 操作。
remove 元素請使用 Iterator方式,如果并發操作,需要對 Iterator 對象加鎖。
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if (刪除元素的條件) {
iterator.remove();
}
}
11、使用HashMap的時候,可以指定集合的初始化大小。
例如說,HashMap里面需要存放10000個元素,但是由于沒有進行初始化大小操作,所以在添加元素的時候,hashmap的內部會一直在進行擴容操作,影響性能。
那么為了減少擴容操作,可以在初始化的時候將hashmap的大小設置為:已知需要存儲的大小/負載因子(0.75)+1
HashMap hashMap=new HashMap<>(13334);
12、Map類集合中,K/V對于null類型存儲的情況:
集合名稱 | key | value | 說明 |
HashMap | 允許為null | 允許為null | 線程不安全 |
TreeMap | 不允許為null | 允許為null | 線程不安全 |
HashTable | 不允許為null | 不允許為null | 線程安全 |
ConcurrentHashMap | 不允許為null | 不允許為null | 線程安全 |
13、可以利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作,避免使用 List 的contains 方法進行遍歷、對比、去重操作。
通關觀察可以發現,HashSet底層通過將傳入的值再傳入到一個HashMap里面去進行操作,進入到HashMap里面之后,會先通過調用該對象的hashcode來判斷是否有重復的值,如果有再進行equals判斷,如果沒有相同元素則插入處理。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
14、線程池不允許使用 Executors 去創建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式讓寫的同學更加明確線程池的運行規則,規避資源耗盡的風險。
錯誤做法:
ExecutorService executors = Executors.newSingleThreadExecutor();
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
對于線程池的參數需要有深入的理解后,結合實際的機器參數來進行參數設置,從而防止在使用中出現異常。
ExecutorService fixedExecutorService = new ThreadPoolExecutor(
1,
2,
60,
TimeUnit.SECONDS,
linkedBlockingQueue,
new MyThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
ps:使用Executors.new方式創建線程池的缺點:
對于FixedThreadPool 和 SingleThreadPool而言
允許的請求隊列長度為 Integer.MAX_VALUE,可能會堆積大量的請求,從而導致 OOM。
對于CachedThreadPool 和 ScheduledThreadPool而言
允許的創建線程數量為 Integer.MAX_VALUE,可能會創建大量的線程,從而導致 OOM。
到此,相信大家對“Java開發常用規范技巧有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。