說明
本博客每週五更新一次。 java語言final修飾符,可以修飾變量、方法和類,傳言可以提升執行效率,實際情況到底如傳言一樣,寫個程序測一下,一切自見分曉。
測試
- 測試分爲三個方面,static工具類final修飾、日誌初始化final修飾、非static類final修飾。
環境
- 電腦:聯想拯救者R700 2020款
- cpu:AMD 4800H
- jdk 1.8.0_181
static工具類final修飾
- 先創建兩個static工具類,一個final修飾,一個正常。
代碼
- final修飾類
public final class StringUtilFinal {
/**
* 判斷字符串是否爲空
*/
public static boolean isEmpty(String str){
if(str==null||str.equals("")||str.length()<=0){
return true;
}
return false;
}
/**
* 判斷字符串是否不爲空
*/
public static boolean isNotEmpty(String str){
return !isEmpty(str);
}
}
- 正常類
public class StringUtilNoFinal {
/**
* 判斷字符串是否爲空
*/
public static boolean isEmpty(String str){
if(str==null||str.equals("")||str.length()<=0){
return true;
}
return false;
}
/**
* 判斷字符串是否不爲空
*/
public static boolean isNotEmpty(String str){
return !isEmpty(str);
}
}
- 測試方法
public void testFinalClass() {
int size=1000000;
String data="12312312";
long start=System.currentTimeMillis();
for(int i=0;i<size;i++) {
StringUtilNoFinal.isNotEmpty(data);
}
System.out.println("No Final Cost Time:"+(System.currentTimeMillis()-start));
start=System.currentTimeMillis();
for(int i=0;i<size;i++) {
StringUtilFinal.isNotEmpty(data);
}
System.out.println("Final Cost Time:"+(System.currentTimeMillis()-start));
}
結果
- 經過幾次1000000次執行,少數相等4ms,final穩定4ms,no final在4和6之間波動。
日誌初始化final修飾
- 類日誌初始化,創建final和非final對象執行,此處日誌系統使用sef4j 1.7.26+logbck 1.2.3
代碼
- 創建代碼
private Logger log = LoggerFactory.getLogger(this.getClass());
private final Logger logFinal = LoggerFactory.getLogger(this.getClass());
- 測試代碼
public void testLog() {
String data="~~我是日誌~~";
int size=100000;
long start=System.currentTimeMillis();
for(int i=0;i<size;i++) {
log.info(data);
}
long value=System.currentTimeMillis()-start;
long startLong=System.currentTimeMillis();
for(int i=0;i<size;i++) {
logFinal.info(data);
}
System.out.println("Log No Final Cost Time:"+value);
System.out.println("Log Final Cost Time:"+(System.currentTimeMillis()-startLong));
}
結果
- 100000次執行後,No Final執行時間2645ms,Final執行時間2821ms,快差不多200ms
非static類final
- 創建final修飾和不修飾的數據類,循環創建。
代碼
- 非final類
public class NoFind {
private String name;
private String address;
private String code;
private String msg;
@Override
public String toString() {
return "Find [address=" + address + ", code=" + code + ", msg=" + msg + ", name=" + name + "]";
}
public void test() {
System.out.println("1231232");
}
}
- final類
public final class Find {
private String name;
private String address;
private String code;
private String msg;
@Override
public String toString() {
return "Find [address=" + address + ", code=" + code + ", msg=" + msg + ", name=" + name + "]";
}
public void test() {
System.out.println("1231232");
}
}
- 測試方法
public void testClass() {
int size=1000000;
long start=System.currentTimeMillis();
Find find;
for(int i=0;i<size;i++) {
find=new Find();
find.toString();
}
System.out.println("No Final Cost Time:"+(System.currentTimeMillis()-start));
start=System.currentTimeMillis();
NoFind noFind;
for(int i=0;i<size;i++) {
noFind=new NoFind();
noFind.toString();
}
System.out.println("Final Cost Time:"+(System.currentTimeMillis()-start));
}
結果
- 運行1000000次,find類執行更快。具體執行時間如下
類 | 僅初始化 | 初始化+toString |
---|---|---|
find | 3ms | 30ms |
no-find | 5ms | 43ms |
結論
- 以上測試是特定環境下的結果,可以作參照。
- static工具類,final修飾類更好
- 普通類日誌對象,不用final修飾
- 普通列final後,效率更高,建議多線程頻繁初始化的類,使用final修飾