final对于访问效率的影响
在能够通过编译的前提下,无论局部变量声明时带不带final关键字修饰,对其访问的效率都一样。
并且:重复访问一个局部变量比重复访问一个成员或静态变量快;即便将其final修饰符去掉,效果也一样。
例如说,以下代码:
static int foo() {
int a = someValueA();
int b = someValueB();
return a + b; // 这里访问局部变量
}
与带final的版本:
static int foo() {
final int a = someValueA();
final int b = someValueB();
return a + b; // 这里访问局部变量
}
效果一模一样,由javac编译得到的字节码会是这样:
invokestatic someValueA:()I
istore_0 // 设置a的值
invokestatic someValueB:()I
istore_1 // 设置b的值
iload_0 // 读取a的值
iload_1 // 读取b的值
iadd
ireturn
字节码里没有任何东西能体现出局部变量的final与否,Class文件里除字节码(Code属性)外的辅助数据结构也没有记录任何体现final的信息。既然带不带final的局部变量在编译到Class文件后都一样了,其访问效率必然一样高,JVM不可能有办法知道什么局部变量原本是用final修饰来声明的。
但有一个例外,那就是声明的“局部变量”并不是一个变量,而是编译时常量的情况:
static int foo2() {
final int a = 2; // 声明常量a
final int b = 3; // 声明常量b
return a + b; // 常量表达式
}
Chapter 4. Types, Values, and Variables
其访问会按照Java语言对常量表达式的规定而做常量折叠。
Chapter 15. Expressions
实际效果跟这样的代码一样:
static int foo3() {
return 5;
}
由javac编译得到对应的字节码会是:
iconst_5 // 常量折叠了,没有“访问局部变量”
ireturn
而这种情况如果去掉final修饰,那么a和b就会被看作普通的局部变量而不是常量表达式,在字节码层面上的效果会不一样
static int foo4() {
int a = 2;
int b = 3;
return a + b;
}
就会编译为:
iconst_2
istore_0 // 设置a的值
iconst_3
istore_1 // 设置b的值
iload_0 // 读取a的值
iload_1 // 读取b的值
iadd
ireturn
但其实这种层面上的差异只对比较简易的JVM影响较大,因为这样的VM对解释器的依赖较大,原本Class文件里的字节码是怎样的它就怎么执行;对高性能的JVM(例如HotSpot、J9等)则没啥影响。这种程度的差异在经过好的JIT编译器处理后又会被消除掉,上例中无论是 foo3() 还是 foo4() 经过JIT编译都一样能被折叠为常量5。
Android里的Dalvik VM虽然是个比较简单的VM,但Android开发套件里的dexopt也可以用来处理这种final的局部“常量”与“变量”的差异,所以实际性能也不会受多少影响。
还有,先把成员或静态变量读到局部变量里保持一定程度的一致性,例如:在同一个方法里连续两次访问静态变量A.x可能会得到不一样的值,因为可能会有并发读写;但如果先有final int x = A.x然后连续两次访问局部变量x的话,那读到的值肯定会是一样的。这种做法的好处通常在有数据竞态但略微不同步没什么问题的场景下,例如说有损计数器之类的。
最后,其实很多人用这种写法的时候根本就没想那么多吧。多半就是为了把代码写短一点,为了把一串很长的名字弄成一个短一点的而把成员或静态变量读到局部变量里,顺便为了避免自己手滑在后面改写了局部变量里最初读到的值而加上final来让编译器(javac之类)检查。
final对于访问效率的影响的更多相关文章
- java提高数据库访问效率代码优化
package com.jb.jubmis.comm; import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQL ...
- linux测试noatime对文件访问时间的影响
linux测试noatime对文件访问时间的影响 文件(如abc)有3个时间: # stat abc Access: 2015-04-16 19:30:13.665970572 +0800 Modif ...
- ejb2.0用本地引用提高EJB访问效率
用本地引用提高EJB访问效率 EJB 1.0和1.1规范只定义了一种在EJB组件中引用另一组件的方法,即通过Bean的远程接口.如果两个Bean都在同一个容器之内,则这种网络开销是不必要的.为解决这个 ...
- 【.NET6】gRPC服务端和客户端开发案例,以及minimal API服务、gRPC服务和传统webapi服务的访问效率大对决
前言:随着.Net6的发布,Minimal API成了当下受人追捧的角儿.而这之前,程序之间通信效率的王者也许可以算得上是gRPC了.那么以下咱们先通过开发一个gRPC服务的教程,然后顺势而为,再接着 ...
- java - day008 -final ,static ,访问控制符.
面向对象 封装 类: 模板 对象: 实例 引用,遥控器 构造方法 新建对象时执行 ...
- as3 中trace() 函数对效率的影响
进行页游开发的过程中,很多开发者都有一个习惯,在数据输出中添加trace()函数来跟踪数值 - 不进行条件编译,发布的时候也不删除.实际上大量的trace函数会降低程序的效率,我们可以用一个简单的例子 ...
- 遍历hashMap对效率的影响
测试环境:jdk1.7.0_79\Processor 1.7 GHz Intel Core i5 遍历Map的方式有很多,通常场景下我们需要的是遍历Map中的Key和Value. 写了两个方法: pu ...
- Hosts文件实际应用 配置内部服务器提高访问效率和速度
一 hosts文件的作用和介绍 https://jingyan.baidu.com/article/335530da45485e19cb41c3d6.html https://www.cnblogs. ...
- MySQL查询where条件的顺序对查询效率的影响<转>
看到有资料说,where条件的顺序会影响查询的效率,根据的逻辑是: where条件的运行是从右到左的,将选择性强的条件放到最右边,可以先过滤掉大部分的数据(而选择性不强的条件过滤后的结果集仍然很大), ...
随机推荐
- CI分页器pagination的原理及实现
以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 下面这段代码是从官网上翻译过来的,介绍了分页的用例 1 2 3 4 5 6 ...
- cron 执行php文件
php执行的命令要写全路径,不然无法执行
- transform和transition
作者:zccst 例如:图片墙 .另外还有,便签墙 使用的样式: 1,正常情况下 ul#index_cards li { background: url("../images/ca ...
- FreeRTOS基础以及UIP之协程--C语言剑走偏锋
在FreeRTOS中和UIP中,都使用到了一种C语言实现的多任务计数,专业的定义叫做协程(coroutine),顾名思义,这是一种协作的例程, 跟具有操作系统概念的线程不一样,协程是在用户空间利用程序 ...
- ORACLE odbc驱动相关
驱动下载 http://www.oracle.com/technetwork/topics/winsoft-085727.html http://www.oracle.com/technetwork/ ...
- linux平台很nice的工具
htop工具 这个是top的升级版,查看进程.内存.CPU等性能的工具,主要是界面很人性化.
- Run Loop简介 分类: ios技术 ios相关 2015-03-11 22:21 73人阅读 评论(0) 收藏
做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深层次的了解它,这样才能在使用的时候得心应手,出 ...
- UnitOfWork实战
企业模式之Unit Of Work模式 在开始UnitOfWork模式之前有必要回顾下我们耳熟能详的Data Access Object(DAO)模式,即数据访问对象.DAO是一种简单的模式,我们构建 ...
- html&&css 基础知识笔记
diV有 Class.Style.title.ID 等属性. 1.margin 空出边缘 margin:上 下 左 右(按顺时针顺序,缺少某一方向则对称) 2.border 边框(三要素:像素 形状 ...
- uWSGI参考资料(1.0版本的配置选项列表)
Reference: http://blog.csdn.net/kevin6216/article/details/15378617 uWSGI参考资料(1.0版本的配置选项列表) 下面的内容包含了大 ...