说明
本博客每周五更新一次。
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修饰