開發與維運

Java工程師如何寫出高效代碼?

1.常量&變量

1.1.直接賦值常量值,禁止聲明新對象

直接賦值常量值,只是創建了一個對象引用,而這個對象引用指向常量值。

反例:
Long i = new Long(1L);
String s = new String("abc");

正例:
Long i = 1L;
String s = "abc";

1.2.當成員變量值無需改變時,儘量定義為靜態常量

在類的每個對象實例中,每個成員變量都有一份副本,而成員靜態常量只有一份實例。

反例:
public class HttpConnection {

private final long timeout = 5L;
...

}

正例:
public class HttpConnection {

private static final long TIMEOUT = 5L;
...

}

1.3.儘量使用基本數據類型,避免自動裝箱和拆箱

Java 中的基本數據類型double、float、long、int、short、char、boolean,分別對應包裝類Double、Float、Long、Integer、Short、Character、Boolean。JVM支持基本類型與對應包裝類的自動轉換,被稱為自動裝箱和拆箱。裝箱和拆箱都是需要CPU和內存資源的,所以應儘量避免使用自動裝箱和拆箱。

反例:
Integer sum = 0;
int[] values = ...;
for (int value : values) {

sum += value; // 相當於result = Integer.valueOf(result.intValue() + value);

}

正例:
int sum = 0;
int[] values = ...;
for (int value : values) {

sum += value;

}

1.4.如果變量的初值會被覆蓋,就沒有必要給變量賦初值

反例:
List userList = new ArrayList<>();
if (isAll) {

userList = userDAO.queryAll();

} else {

userList = userDAO.queryActive();

}

正例:
List userList;
if (isAll) {

userList = userDAO.queryAll();

} else {

userList = userDAO.queryActive();

}

1.5.儘量使用函數內的基本類型臨時變量

在函數內,基本類型的參數和臨時變量都保存在棧(Stack)中,訪問速度較快;對象類型的參數和臨時變量的引用都保存在棧(Stack)中,內容都保存在堆(Heap)中,訪問速度較慢。在類中,任何類型的成員變量都保存在堆(Heap)中,訪問速度較慢。

反例:
public final class Accumulator {

private double result = 0.0D;
public void addAll(@NonNull double[] values) {
    for(double value : values) {
        result += value;
    }
}
...

}

正例:
public final class Accumulator {

private double result = 0.0D;
public void addAll(@NonNull double[] values) {
    double sum = 0.0D;
    for(double value : values) {
        sum += value;
    }
    result += sum;
}
...

}

1.6.儘量不要在循環體外定義變量

在老版JDK中,建議“儘量不要在循環體內定義變量”,但是在新版的JDK中已經做了優化。通過對編譯後的字節碼分析,變量定義在循環體外和循環體內沒有本質的區別,運行效率基本上是一樣的。

反而,根據“ 局部變量作用域最小化 ”原則,變量定義在循環體內更科學更便於維護,避免了延長大對象生命週期導致延緩回收問題 。

Leave a Reply

Your email address will not be published. Required fields are marked *