使用final关键字真的能提高性能吗?
首先这里有一篇文章:
http://www.javamex.com/tutorials/java_final_performance.shtml
在这篇文章中,作者Neil Coffey说到了下面一些内容:
But to the best of my knowledge, there are no class/method optimisations in Hotspot based on whether or not a class or method is final. In a discussion with members of the Hotspot compiler team back in 2005, they confirmed this was already the case then.
这段话的大致意思是,据作者所知,在Hotspot中没有任何的优化是基于一个类或者一个方法是否是final的。在2005年与Hotspot开发团队的一次讨论中,他们证实了这种情况。
接着作者进行了一个性能测试,测试内容是先有一个基类BaseClass,在基类中定义一个方法A;然后定义三个子类:①ClassA 继承基类②ClassB继承基类并定义为final③classC继承基类,并且被其他类继承;三个子类分别用相同的内容覆写方法A。因为对于每个子类,使用时都有两种方式,例如
BaseClass classA = new ClassA();或
ClassA classA = new ClassA();
因此这里有6种调用方法A的方式,分别对比方法调用的耗时。
结果是:
结果表明,class是否由final修饰不会影响性能,同时第二种声明方法相对更高效,但是第二种有时不符合我们面向接口编程的原则,所以这里存在取舍。
对于final提高性能还有另一种可能,就是编译器倾向于将用final修饰的短方法内联(inline)。文中提到在早期的字节码编译器中错误地采取这种判断内联的方法,而在现代的Java编译器中不再这样。在Hotspot虚拟机中,它的优化是基于JIT技术,而不是基于你是否将方法标记为final。遗憾的是作者并没有对此进行测试,所以这里我们就自己来设计测试。代码如下
public class FinalVsNonFinal
{
private static final int TIMES = 10_0000;
public static void main(String[] args) {
FinalVsNonFinal o = new FinalVsNonFinal();
//多测试几次,看看情况
//输出时间的单位是毫秒
for(int i = 0; i < 4; i++) {
testFinal(o);
testNonFinal(o);
}
}
public final boolean methodA() {
return true;
}
public boolean methodB() {
return true;
}
public static void testFinal(FinalVsNonFinal o) {
long start = System.nanoTime();
for(int i = 0; i < TIMES; i++) {
o.methodA();
}
long duration = System.nanoTime() - start;
System.out.println("Final Method: " + duration/1.0e6);
}
public static void testNonFinal(FinalVsNonFinal o) {
long start = System.nanoTime();
for(int i = 0; i < TIMES; i++) {
o.methodB();
}
long duration = System.nanoTime() - start;
System.out.println("Non-Final Method: " + duration/1.0e6);
}
}
运行结果的截图是:
(我的jdk版本是jdk1.7.0_03,系统是windows 7,cpu是AMD turion RM75)
从上面的截图可以看出,final方法和non-final方法的耗时差不多,但是第1次双方都耗时较多,而后面2次的调用耗时越来越少。在这里,后几次时间的减少就是由于JIT技术,有兴趣的可以去了解下Java中的JIT技术。
综上所述, Java中的final关键字更多是用在设计上,而final关键字本身并不能带来性能的提升。
- 大小: 6.6 KB
分享到:
相关推荐
模拟Objective-C中Java的final或C#的密封关键字的保护 该库允许将类标记为 final - 防止它被子类化,或将单个方法标记为 final - 防止它们在子类中被覆盖。 与 Java 和 C# 等效项相比,这些检查在运行时发生,而不是...
1. 我们能不能声明 main()方法为非静态?...使用 final 关键字修饰一个变量时, 是指引用变量不能变, 引用变量所指向的对象中的 容还是可以改变的。 5. string、 stringbuilder、 stringbuffer 区别
1. final的关键字提高了性能,JVM和java应用会缓存final变量 2. final变量可以在多线程环境下保持线程安全 3. 使用final的关键字提
使用final关键字以提高性能和明确意图(不可变对象)。 明确初始化变量,避免产生未定义行为。 遵循“早初始化,晚赋值”原则。 面向对象设计: 尽量使类具有高内聚低耦合特性。 优先考虑接口而不是实现,利用多态...
修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被...
156、在jsp:useBean语法中使用beanName有何好处? 37 157、当我使用时,在浏览器的地址栏没有改变? 37 158、如何转换JSP 0.9版本的文件到JSP1.1? 37 160、JSP和Servlet有哪些相同点和不同点,他们之间的联系是什么...
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11、"=="和equals方法究竟有什么区别? 12、静态变量和实例变量的区别? 13、是否可以从一个static方法内部发出对非static方法的调用? ...
学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...
java.lang.String类是final类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类 3、int 和 Integer 有什么区别 Java 提供两种不同的类型:引用类型和原始类型(或内置...
6.8 final关键字 6.8.1 final数据 6.8.2 final方法 6.8.3 final类 6.8.4 final的注意事项 6.9 初始化和类装载 6.9.1 继承初始化 6.10 总结 6.11 练习 第7章 多形性 7.1 上溯造型 7.1.1 为什么要上溯造型 7.2 深入...
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"=="和equals方法究竟有什么区别? 11 12、静态变量和实例变量的区别? 12 13、是否可以从一个static方法内部发出对非static方法...
6.8 final关键字 6.8.1 final数据 6.8.2 final方法 6.8.3 final类 6.8.4 final的注意事项 6.9 初始化和类装载 6.9.1 继承初始化 6.10 总结 6.11 练习 第7章 多形性 7.1 上溯造型 7.1.1 为什么要上溯造型 7.2 深入...
Java 基础学习笔记,主要包括: 10_Java常见对象.md 10_Java常见对象_2.md 1_数据类型.md 3_运算.md ...由于Java的高性能和稳定性,许多大型企业和互联网公司选择使用Java开发核心业务系统和高并发的We
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"=="和equals方法究竟有什么区别? 11 12、静态变量和实例变量的区别? 12 13、是否可以从一个static方法内部发出对非static方法...
6.8 final关键字 6.8.1 final数据 6.8.2 final方法 6.8.3 final类 6.8.4 final的注意事项 6.9 初始化和类装载 6.9.1 继承初始化 6.10 总结 6.11 练习 第7章 多形性 7.1 上溯造型 7.1.1 为什么要上溯造型 7.2 深入...
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"=="和equals方法究竟有什么区别? 11 12、静态变量和实例变量的区别? 12 13、是否可以从一个static方法内部发出对非static方法...
10、使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 11 11、"=="和equals方法究竟有什么区别? 11 12、静态变量和实例变量的区别? 12 13、是否可以从一个static方法内部发出对非static方法...
Java基础 6 1. 面向对象的特征有哪些方面 6 2. String是最基本的数据类型吗? 7 3. int 和 Integer 有什么区别 7 4. String 和StringBuffer的区别 7 5. 运行时异常与一般异常有何异同? 7 6. 说出ArrayList,Vector, ...
6.8 final关键字 6.8.1 final数据 6.8.2 final方法 6.8.3 final类 6.8.4 final的注意事项 6.9 初始化和类装载 6.9.1 继承初始化 6.10 总结 6.11 练习 第7章 多形性 7.1 上溯造型 7.1.1 为什么要上溯造型 7.2 深入...