[TOC]
### **1. return 一個空的集合,而不是 null**
如果一個程序返回一個沒有任何值的集合,請確保一個空集合返回,而不是空元素。這樣你就不用去寫一大堆 ”if else” 判斷null元素。

Java的標準庫設計者已經在 Collections 類中放了一個空的 List 常量 EMPTY\_LIST,除此之外,還有 EMPTY\_MAP, EMPTY\_SET
### **2. 小心使用 String連接**
因為字符串相加或者拼接的方式都會在對象池中查找字符串是否存在,如果不存在則創建,這樣在拼接的過程中會產生大量中間過程的字符串,占用內存資源。StringBuilder效率優于StringBuffer,但是StringBuffer線程安全。
### 3. 避免空指針
下面說幾個空指針的幾個最常見的案例及解決之道。
#### 1、字符串比較,常量放前面
~~~
if(status.equals(SUCCESS)){
}
~~~
這個時候 status 可能為 null 造成空指針異常,應該把常量放前面,就能避免空指針異常。
~~~
if(SUCCESS.equals(status)){
}
~~~
這個應該在各種開發規范里面都會提到,也是最基礎的。
#### 2、初始化默認值
在對象初始化的時候給它一個默認值或者默認構造實現,如:
~~~
User user = new User();
String name = StringUtils.EMPTY;
~~~
#### 3、返回空集合
在返回一個集合的話,默認會是 null,統一規范返回一個空集合。
舉個 List 例子,如:
~~~
public List getUserList(){
List list = userMapper.gerUserList();
return list == null ? new ArrayList() : list;
}
~~~
這樣接收方就不用擔心空指針異常了,也不會影響業務。
#### 4、斷言
斷言是用來檢查程序的安全性的,在使用之前進行檢查條件,如果不符合條件就報異常,符合就繼續。
Java 中自帶的斷言關鍵字:assert,如:
~~~
assert name == null : "名稱不能為空";
~~~
輸出:
~~~
Exception in thread "main" java.lang.AssertionError: 名稱不正確
~~~
不過默認是不啟動斷言檢查的,需要要帶上 JVM 參數:-enableassertions 才能生效。
Java 中這個用的很少,建議使用 Spring 中的,更強大,更方便好用。
Spring中的用法:
~~~
Assert.notNull(name,"名稱不能為空");
~~~
#### 5、Optional
Optional 是 JDK 8 新增的新特性,再也不用 != null 來判斷了,這個在一個對象里面的多個子對象連續判斷的時候非常有用。
### 4. 檢查null和長度
> 不管什么時候你有一個集合、數組或者其他的,確保它存在并且不為空。
> 在學習前期這樣的行為對你來說可能是多此一舉,但對于已經工作或者做過項目的小伙伴來說,相信這樣的代碼對
Java7的Objects工具類,提供類對Object的相關操作

### 5. switch語句末尾總是加上default
```
int num = 4;
switch (num){
case 1:
System.out.println("值為1");
break;
case 2:
System.out.println("值為2");
break;
default:
System.out.println("無此值");
}
```
### 6. 使用 String.valueOf(value) 代替 ""+value
將其他值轉換成字符串時,這樣String.valueOf(value)效率會更高
```
Integer num = 1;
String str = "" + num;
String string = String.valueOf(num);
System.out.println(str);
System.out.println(string);
```
### 7. 盡量使用基本數據類型代替對象
```
String str = “hello”;
```
> 上面這種方式會創建一個“hello”字符串,而且JVM的字符緩存池還會緩存這個字符串
```
String str = new String(“hello”);
```
> 此時程序除創建字符串外,str所引用的String對象底層還包含一個char數組,這個char數組依次存放了h,e,l,l,o
### 8. 不要用 NullPointerException進行空指針捕獲
> 空指針異常應該用代碼規避(比如檢測不為空),而不是用捕獲異常的方式處理
### 9. Bean 中的鏈式風格
什么是鏈式風格?我來舉個例子,看下面這個 Student 的 Bean:
~~~
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public Student setName(String name) {
this.name = name;
return this;
}
public int getAge() {
return age;
}
public Student setAge(int age) {
return this;
}
}
~~~
仔細看一下 set 方法,這樣的設置便是 chain 的 style,調用的時候,可以這樣使用:
~~~
Student student = new Student()
.setAge(24)
.setName("zs");
~~~
相信合理使用這樣的鏈式代碼,會更多的程序帶來很好的可讀性,那看一下**如果使用 Lombok 進行改善呢,請使用 @Accessors(chain = true),看如下代碼:**
~~~
@Accessors(chain = true)
@Setter
@Getter
public class Student {
private String name;
private int age;
}
~~~
這樣就完成了一個對于 Bean 來講很友好的鏈式操作。
### 10. Lombok靜態構造方法
使用lombok(@RequiredArgsConstructor 和 @NonNull):
~~~
@Accessors(chain = true)
@Setter
@Getter
@RequiredArgsConstructor(staticName = "ofName")
public class Student {
@NonNull private String name;
private int age;
}
~~~
測試代碼:
~~~text
Student student = Student.ofName("zs");
~~~
這樣構建出的 bean 語義是否要比直接 new 一個含參的構造方法(包含 name 的構造方法)要好很多。當然,看過很多源碼以后,我想相信將靜態構造方法 ofName 換成 of 會先的更加簡潔:
~~~
@Accessors(chain = true)
@Setter
@Getter
@RequiredArgsConstructor(staticName = "of")
public class Student {
@NonNull private String name;
private int age;
}
~~~
測試代碼:
~~~
Student student = Student.of("zs");
~~~
當然它仍然是支持鏈式調用的:
~~~
Student student = Student.of("zs").setAge(24);
~~~
這樣來寫代碼,真的很簡潔,并且可讀性很強。
### 11. 使用 Builder
Builder 模式我不想再多解釋了,讀者可以看一下 Head First(《設計模式》)的建造者模式。
今天其實要說的是一種變種的 Builder 模式,那就是構建 Bean 的 Builder 模式,其實主要的思想是帶著大家一起看一下 Lombok 給我們帶來了什么。
看一下 Student 這個類的原始 Builder 狀態:
~~~
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static Builder builder(){
return new Builder();
}
public static class Builder{
private String name;
private int age;
public Builder name(String name){
this.name = name;
return this;
}
public Builder age(int age){
this.age = age;
return this;
}
public Student build(){
Student student = new Student();
student.setAge(age);
student.setName(name);
return student;
}
}
}
~~~
調用方式:
~~~
Student student = Student.builder().name("zs").age(24).build();
~~~
這樣的 Builder 代碼,讓我是在惡心難受,于是我打算用 Lombok 重構這段代碼:
~~~
@Builder
public class Student {
private String name;
private int age;
}
~~~
調用方式:
~~~
Student student = Student.builder().name("zs").age(24).build();
~~~
### 13. 復雜代碼拆分,減少代碼層級
- 計算機網絡
- 基礎_01
- tcp/ip
- http轉https
- Let's Encrypt免費ssl證書(基于haproxy負載)
- what's the http?
- 網關
- 網絡IO
- http
- 工具
- Git
- 初始本地倉庫并上傳
- git保存密碼
- Gitflow
- maven
- 1.生命周期命令
- 聚合與繼承
- 插件管理
- assembly
- 資源管理插件
- 依賴范圍
- 分環境打包
- dependencyManagement
- 版本分類
- 找不到主類
- 無法加載主類
- 私服
- svn
- gradle
- 手動引入第三方jar包
- 打包exe文件
- Windows
- java
- 設計模式
- 七大原則
- 1.開閉原則
- 2. 里式替換原則
- 3. 依賴倒置原則
- 4. 單一職責原則
- 單例模式
- 工廠模式
- 簡單工廠
- 工廠方法模式
- 抽象工廠模式
- 觀察者模式
- 適配器模式
- 建造者模式
- 代理模式
- 適配器模式
- 命令模式
- json
- jackson
- poi
- excel
- easy-poi
- 規則
- 模板
- 合并單元格
- word
- 讀取
- java基礎
- 類路徑與jar
- 訪問控制權限
- 類加載
- 注解
- 異常處理
- String不可變
- 跨域
- transient關鍵字
- 二進制編碼
- 泛型1
- 與或非
- final詳解
- Java -jar
- 正則
- 讀取jar
- map
- map計算
- hashcode計算原理
- 枚舉
- 序列化
- URLClassLoader
- 環境變量和系統變量
- java高級
- java8
- 1.Lambda表達式和函數式接口
- 2.接口的默認方法和靜態方法
- 3.方法引用
- 4.重復注解
- 5.類型推斷
- 6.拓寬注解的應用場景
- java7-自動關閉資源機制
- 泛型
- stream
- 時區的正確理解
- StringJoiner字符串拼接
- 注解
- @RequestParam和@RequestBody的區別
- 多線程
- 概念
- 線程實現方法
- 守護線程
- 線程阻塞
- 筆試題
- 類加載
- FutureTask和Future
- 線程池
- 同步與異步
- 高效簡潔的代碼
- IO
- ThreadLocal
- IO
- NIO
- 圖片操作
- KeyTool生成證書
- 壓縮圖片
- restful
- 分布式session
- app保持session
- ClassLoader.getResources 能搜索到的資源路徑
- java開發規范
- jvm
- 高并發
- netty
- 多線程與多路復用
- 異步與事件驅動
- 五種IO模型
- copy on write
- code style
- 布隆過濾器
- 筆試
- 數據庫
- mybatis
- mybatis與springboot整合配置
- pagehelper
- 分頁數據重復問題
- Java與數據庫之間映射
- 攔截器
- 攔截器應用
- jvm
- 堆內存測試
- 線程棧
- 直接內存
- 內存結構
- 內存模型
- 垃圾回收
- 調優
- 符號引用
- 運行參數
- 方法區
- 分帶回收理論
- 快捷開發
- idea插件
- 注釋模板
- git
- pull沖突
- push沖突
- Excel處理
- 圖片處理
- 合并單元格
- easypoi
- 模板處理
- 響應式編程
- reactor
- reactor基礎
- jingyan
- 規范
- 數據庫