1.利用語法
1.1.利用三元表達式
普通:
String title;
if (isMember(phone)) {
title = "會員";
} else {
title = "遊客";
}
精簡:
String title = isMember(phone) ? "會員" : "遊客";
注意:對於包裝類型的算術計算,需要注意避免拆包時的空指針問題。
1.2.利用 for-each 語句
從 Java 5 起,提供了 for-each 循環,簡化了數組和集合的循環遍歷。 for-each 循環允許你無需保持傳統 for 循環中的索引就可以遍歷數組,或在使用迭代器時無需在 while 循環中調用 hasNext 方法和 next 方法就可以遍歷集合。
普通:
double[] values = ...;
for(int i = 0; i < values.length; i++) {
double value = values[i];
// TODO: 處理value
}
List<Double> valueList = ...;
Iterator<Double> iterator = valueList.iterator();
while (iterator.hasNext()) {
Double value = iterator.next();
// TODO: 處理value
}
精簡:
double[] values = ...;
for(double value : values) {
// TODO: 處理value
}
List<Double> valueList = ...;
for(Double value : valueList) {
// TODO: 處理value
}
1.3.利用 try-with-resource 語句
所有實現 Closeable 接口的“資源”,均可採用 try-with-resource 進行簡化。
普通:
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("cities.csv"));
String line;
while ((line = reader.readLine()) != null) {
// TODO: 處理line
}
} catch (IOException e) {
log.error("讀取文件異常", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.error("關閉文件異常", e);
}
}
}
精簡:
try (BufferedReader reader = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
// TODO: 處理line
}
} catch (IOException e) {
log.error("讀取文件異常", e);
}
1.4.利用 return 關鍵字
利用 return 關鍵字,可以提前函數返回,避免定義中間變量。
普通:
public static boolean hasSuper(@NonNull List<UserDO> userList) {
boolean hasSuper = false;
for (UserDO user : userList) {
if (Boolean.TRUE.equals(user.getIsSuper())) {
hasSuper = true;
break;
}
}
return hasSuper;
}
精簡:
public static boolean hasSuper(@NonNull List<UserDO> userList) {
for (UserDO user : userList) {
if (Boolean.TRUE.equals(user.getIsSuper())) {
return true;
}
}
return false;
}
1.5.利用 static 關鍵字
利用 static 關鍵字,可以把字段變成靜態字段,也可以把函數變爲靜態函數,調用時就無需初始化類對象。
普通:
public final class GisHelper {
public double distance(double lng1, double lat1, double lng2, double lat2) {
// 方法實現代碼
}
}
GisHelper gisHelper = new GisHelper();
double distance = gisHelper.distance(116.178692D, 39.967115D, 116.410778D, 39.899721D);
精簡:
public final class GisHelper {
public static double distance(double lng1, double lat1, double lng2, double lat2) {
// 方法實現代碼
}
}
double distance = GisHelper.distance(116.178692D, 39.967115D, 116.410778D, 39.899721D);
1.6.利用 lambda 表達式
Java 8 發佈以後,lambda 表達式大量替代匿名內部類的使用,在簡化了代碼的同時,更突出了原有匿名內部類中真正有用的那部分代碼。
普通:
new Thread(new Runnable() {
public void run() {
// 線程處理代碼
}
}).start();
精簡:
new Thread(() -> {
// 線程處理代碼
}).start();
1.7.利用方法引用
方法引用(::),可以簡化 lambda 表達式,省略變量聲明和函數調用。
普通:
Arrays.sort(nameArray, (a, b) -> a.compareToIgnoreCase(b));
List<Long> userIdList = userList.stream()
.map(user -> user.getId())
.collect(Collectors.toList());
精簡:
Arrays.sort(nameArray, String::compareToIgnoreCase);
List<Long> userIdList = userList.stream()
.map(UserDO::getId)
.collect(Collectors.toList());
1.8.利用 unchecked 異常
Java 的異常分爲兩類:Checked 異常和 Unchecked 異常。Unchecked 異常繼承了RuntimeException ,特點是代碼不需要處理它們也能通過編譯,所以它們稱作 Unchecked 異常。利用 Unchecked 異常,可以避免不必要的 try-catch 和 throws 異常處理。
普通:
@Service
public class UserService {
public void createUser(UserCreateVO create, OpUserVO user) throws BusinessException {
checkOperatorUser(user);
...
}
private void checkOperatorUser(OpUserVO user) throws BusinessException {
if (!hasPermission(user)) {
throw new BusinessException("用戶無操作權限");
}
...
}
...
}
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/createUser")
public Result<Void> createUser(@RequestBody @Valid UserCreateVO create, OpUserVO user) throws BusinessException {
userService.createUser(create, user);
return Result.success();
}
...
}
精簡:
@Service
public class UserService {
public void createUser(UserCreateVO create, OpUserVO user) {
checkOperatorUser(user);
...
}
private void checkOperatorUser(OpUserVO user) {
if (!hasPermission(user)) {
throw new BusinessRuntimeException("用戶無操作權限");
}
...
}
...
}
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/createUser")
public Result<Void> createUser(@RequestBody @Valid UserCreateVO create, OpUserVO user) {
userService.createUser(create, user);
return Result.success();
}
...
}
2.利用註解
2.1.利用 Lombok 註解
Lombok 提供了一組有用的註解,可以用來消除Java類中的大量樣板代碼。
普通:
public class UserVO {
private Long id;
private String name;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
...
}
精簡:
@Getter
@Setter
@ToString
public class UserVO {
private Long id;
private String name;
...
}
2.2.利用 Validation 註解
普通:
@Getter
@Setter
@ToString
public class UserCreateVO {
@NotBlank(message = "用戶名稱不能爲空")
private String name;
@NotNull(message = "公司標識不能爲空")
private Long companyId;
...
}
@Service
@Validated
public class UserService {
public Long createUser(@Valid UserCreateVO create) {
// TODO: 創建用戶
return null;
}
}
精簡:
@Getter
@Setter
@ToString
public class UserCreateVO {
@NotBlank(message = "用戶名稱不能爲空")
private String name;
@NotNull(message = "公司標識不能爲空")
private Long companyId;
...
}
@Service
@Validated
public class UserService {
public Long createUser(@Valid UserCreateVO create) {
// TODO: 創建用戶
return null;
}
}
2.3.利用 @NonNull 註解
Spring 的 @NonNull 註解,用於標註參數或返回值非空,適用於項目內部團隊協作。只要實現方和調用方遵循規範,可以避免不必要的空值判斷,這充分體現了阿里的“新六脈神劍”提倡的“因爲信任,所以簡單”。
普通:
public List<UserVO> queryCompanyUser(Long companyId) {
// 檢查公司標識
if (companyId == null) {
return null;
}
// 查詢返回用戶
List<UserDO> userList = userDAO.queryByCompanyId(companyId);
return userList.stream().map(this::transUser).collect(Collectors.toList());
}
Long companyId = 1L;
List<UserVO> userList = queryCompanyUser(companyId);
if (CollectionUtils.isNotEmpty(userList)) {
for (UserVO user : userList) {
// TODO: 處理公司用戶
}
}
精簡:
public @NonNull List<UserVO> queryCompanyUser(@NonNull Long companyId) {
List<UserDO> userList = userDAO.queryByCompanyId(companyId);
return userList.stream().map(this::transUser).collect(Collectors.toList());
}
Long companyId = 1L;
List<UserVO> userList = queryCompanyUser(companyId);
for (UserVO user : userList) {
// TODO: 處理公司用戶
}