代码优化
1. 对类使用构建者模式进行构建
- 内部静态类提供构建方法
- 实现将一个复杂对象的构建过程与它的表示分离开来,使得同样的构建过程可以创建不同的表示。这一模式可以使对象的构建过程更加灵活、简洁和可维护。
public class Example<T> implements Serializable {
private static final long serialVersionUID = 6914775178403410109L;
private String returnCode;
private String returnMsg;
private T body;
public static <T> Example.ExampleBuilder<T> builder() {
return new Example.ExampleBuilder();
}
public String getReturnCode() {
return this.returnCode;
}
public String getReturnMsg() {
return this.returnMsg;
}
public T getBody() {
return this.body;
}
public void setReturnCode(String returnCode) {
this.returnCode = returnCode;
}
public void setReturnMsg(String returnMsg) {
this.returnMsg = returnMsg;
}
public void setBody(T body) {
this.body = body;
}
public boolean equals(Object o) {
...
}
public int hashCode() {
...
}
public String toString() {
return "Example(returnCode=" + this.getReturnCode() + ", returnMsg=" + this.getReturnMsg() + ", body=" + this.getBody() + ")";
}
public Example() {
}
public Example(String returnCode, String returnMsg, T body) {
this.returnCode = returnCode;
this.returnMsg = returnMsg;
this.body = body;
}
public static class ExampleBuilder<T> {
private String returnCode;
private String returnMsg;
private T body;
ExampleBuilder() {
}
public Example.ExampleBuilder<T> returnCode(String returnCode) {
this.returnCode = returnCode;
return this;
}
public Example.ExampleBuilder<T> returnMsg(String returnMsg) {
this.returnMsg = returnMsg;
return this;
}
public Example.ExampleBuilder<T> body(T body) {
this.body = body;
return this;
}
public Example<T> build() {
return new Example(this.returnCode, this.returnMsg, this.body);
}
public String toString() {
return "Example.ExampleBuilder(returnCode=" + this.returnCode + ", returnMsg=" + this.returnMsg + ", body=" + this.body + ")";
}
}
}
2. switch的case使用枚举
3. 泛型
使代码具有更高复用性和类型安全性的编程方式
通过参数化类型实现,可以用在类、接口和方法中
3.1 泛型类
public class Box<T> {
private T item;
public void set(T item) {
this.item = item;
}
public T get() {
return item;
}
public static void main(String[] args) {
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
System.out.println("String: " + stringBox.get());
Box<Integer> intBox = new Box<>();
intBox.set(123);
System.out.println("Integer: " + intBox.get());
}
}
3.2 泛型接口
public interface Pair<K, V> {
K getKey();
V getValue();
}
public class KeyValue<K, V> implements Pair<K, V> {
private K key;
private V value;
public KeyValue(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
public static void main(String[] args) {
Pair<String, Integer> pair = new KeyValue<>("Age", 25);
System.out.println(pair.getKey() + ": " + pair.getValue());
}
}
3.3 泛型方法
public class GenericMethodExample {
public static <T> void printArray(T[] array) {
for (T element : array) {
System.out.print(element + " ");
}
System.out.println();
}
public static void main(String[] args) {
Integer[] intArray = {1, 2, 3, 4};
String[] strArray = {"A", "B", "C"};
printArray(intArray); // 输出: 1 2 3 4
printArray(strArray); // 输出: A B C
}
}
3.4 泛型约束
通配符
通配符通过 ? 表示,表示一种未知类型。
- ? extends T:表示上界通配符,匹配 T 或 T 的子类。
- ? super T:表示下界通配符,匹配 T 或 T 的父类。
上界示例(读取数据):
import java.util.ArrayList;
import java.util.List;
public class WildcardExample {
public static void printNumbers(List<? extends Number> list) {
for (Number number : list) {
System.out.println(number);
}
}
public static void main(String[] args) {
List<Integer> integers = List.of(1, 2, 3);
List<Double> doubles = List.of(1.1, 2.2, 3.3);
printNumbers(integers);
printNumbers(doubles);
}
}
下界示例(写入数据):
import java.util.ArrayList;
import java.util.List;
public class LowerBoundExample {
public static void addNumbers(List<? super Integer> list) {
list.add(10);
list.add(20);
}
public static void main(String[] args) {
List<Number> numbers = new ArrayList<>();
addNumbers(numbers);
System.out.println(numbers);
}
}
4. 使用线程池和@Async注解
5. 不影响主业务的流程使用消息队列
6. 合理使用异常
java.lang.Object
↳ java.lang.Throwable
↳ java.lang.Exception
↳ java.lang.RuntimeException
理解 Exception
和 RuntimeException
的使用场景,主要取决于异常的 可预测性 和 是否需要强制调用方处理
抛出Exception(检查异常,Checked Exception)
- 什么时候用?
业务异常或可恢复的异常:调用方可以且应该采取措施处理异常。
适用于资源访问类异常(文件、数据库、网络等),这些异常往往是可以预期并且需要显式处理的。 - 特点:
调用方必须捕获或显式抛出(通过 throws 声明)。
抛出RuntimeException(运行时异常,Unchecked Exception)
- 什么时候用?
程序逻辑或编程错误:调用方通常无法修复这类异常,更多是暴露开发者的错误或逻辑问题。
如空指针、非法参数、索引越界等,这些异常本质上是不可恢复的。 - 特点:
调用方可以选择是否处理,但通常不需要强制处理。
场景举例
场景 | 建议抛出的异常 | 原因 |
---|---|---|
调用第三方接口失败 | Exception 或自定义业务异常 | 可预期的异常,调用方可能需要处理或重试。 |
数据库更新失败 | RuntimeException 或 DataAccessException | 不可恢复的异常,应由事务管理器自动处理。 |
校验入参失败 | IllegalArgumentException 或自定义异常 (RuntimeException ) | 通常是开发者逻辑错误,或与业务相关的校验失败。 |
计算中数据异常 | ArithmeticException 或 IllegalStateException(RuntimeException ) | 编程逻辑错误或对象状态不符的异常。 |
7. 显示声明serialVersionUID
serialVersionUID
是Java序列化机制中的一个静态字段,用于表示类的版本。如果一个类实现了Serializable接口,它可以被序列化和反序列化。在序列化过程中,对象被转换为字节流;在反序列化过程中,字节流被转换回对象。
- 序列化:将对象的状态转换为字节流,以便保存到文件、发送到网络等。
- 反序列化:将字节流转换回对象。
serialVersionUID用于控制类的版本。当一个类的定义发生变化时,例如添加或删除字段,序列化和反序列化过程中可能会出现不兼容的情况。serialVersionUID可以帮助确保在类的版本不匹配时捕获到异常。
IDEA设置serialVersionUID警告
方便手动生成serialVersionUID