当前位置: 首页 > wzjs >正文

温州市建设工程质量安全管理总站虞城网站建设

温州市建设工程质量安全管理总站,虞城网站建设,微信搜一搜seo优化,如何做自己的业务网站问题 final修饰的字段就一定是不能重新赋值吗? 基础知识 常量变量是使用常量表达式初始化的原始类型或 String 类型的最终变量。变量是否为常量变量可能对类初始化、二进制兼容性和明确赋值有影响。 —Java 语言规范 实验 用例源码-重新赋值 import java.lang.reflect.Fie…

问题

final修饰的字段就一定是不能重新赋值吗?

基础知识

常量变量是使用常量表达式初始化的原始类型或 String 类型的最终变量。变量是否为常量变量可能对类初始化、二进制兼容性和明确赋值有影响。 —Java 语言规范

实验

用例源码-重新赋值

import java.lang.reflect.Field;public class ConstantValues {final int fieldInit = 42;final int instanceInit;final int constructor;{instanceInit = 42;}public ConstantValues() {constructor = 42;}static void set(ConstantValues p, String field) throws Exception {Field f = ConstantValues.class.getDeclaredField(field);f.setAccessible(true);f.setInt(p, 9000);}public static void main(String... args) throws Exception {ConstantValues p = new ConstantValues();set(p, "fieldInit");set(p, "instanceInit");set(p, "constructor");System.out.println(p.fieldInit + " " + p.instanceInit + " " + p.constructor);}}

执行结果

42 9000 9000

如上述执行结果所示,上面有3个被final关键字修饰的字段,其中的fieldInit字段赋有初值,其他两个没有赋初值,而在后续的通过Java反射机制对上述的3个被final修饰字段重新赋值后,执行结果惊奇的发现赋有初值的fieldInit字段的值没有被修改,其他两个没有赋初值的字段的值发生了修改,那这是因为什么呢?我们可以通过查看通过javac静态编译的字节码一查究竟,如下述代码所示:

$ javap -c -v -p ConstantValues.class
...final int fieldInit;descriptor: Iflags: ACC_FINALConstantValue: int 42  <---- oh...final int instanceInit;descriptor: Iflags: ACC_FINALfinal int constructor;descriptor: Iflags: ACC_FINAL...
public static void main(java.lang.String...) throws java.lang.Exception;descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGSCode:...41: bipush        42   // <--- Oh wow, inlined fieldInit field43: invokevirtual #18  // StringBuilder.append46: ldc           #19  // String " "48: invokevirtual #20  // StringBuilder.append51: aload_152: getfield      #3   // Field instanceInit:I55: invokevirtual #18  // StringBuilder.append58: ldc           #19  // String ""60: invokevirtual #20  // StringBuilder.append63: aload_164: getfield      #4   // Field constructor:I67: invokevirtual #18  // StringBuilder.append70: invokevirtual #21  // StringBuilder.toString73: invokevirtual #22  // System.out.println

通过查看上述字节码可以看出,被初始化赋值的fieldInit字段其实在javac静态编译时已经通过内联操作赋值了,而对于在JVM动态编译时不可能重新重写字节码,所以从此我们可以看出已经进行初始化赋值的由final关键字修饰的字段是不能修改的,而未进行初始化赋值的由final关键字修饰的字段却是可以进行修改的。理论上进行初始化赋值的由final关键字修饰的字段性能表现肯定要比没有进行初始化赋值的由final关键字修饰的字段要好,我们可以通过下面的测试用例进行进一步的验证。

用例源码-是否有final修饰的已初始化字段

@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class FinalInitBench {// Too lazy to actually build the example class with constructor that initializes// final fields, like we have in production code. No worries, we shall just model// this with naked fields. Right?final int fx = 42;  // Compiler complains about initialization? Okay, put 42 right here!int x  = 42;@Benchmarkpublic int testFinal() {return fx;}@Benchmarkpublic int test() {return x;}
}

执行结果

Benchmark                                  Mode  Cnt   Score    Error  Units
FinalInitBench.test                        avgt    9   1.920 ±  0.002  ns/op
FinalInitBench.test:CPI                    avgt    3   0.291 ±  0.039   #/op
FinalInitBench.test:L1-dcache-loads        avgt    3  11.136 ±  1.447   #/op
FinalInitBench.test:L1-dcache-stores       avgt    3   3.042 ±  0.327   #/op
FinalInitBench.test:cycles                 avgt    3   7.316 ±  1.272   #/op
FinalInitBench.test:instructions           avgt    3  25.178 ±  2.242   #/opFinalInitBench.testFinal                   avgt    9   1.901 ±  0.001  ns/op
FinalInitBench.testFinal:CPI               avgt    3   0.285 ±  0.004   #/op
FinalInitBench.testFinal:L1-dcache-loads   avgt    3   9.077 ±  0.085   #/op  <--- !
FinalInitBench.testFinal:L1-dcache-stores  avgt    3   4.077 ±  0.752   #/op
FinalInitBench.testFinal:cycles            avgt    3   7.142 ±  0.071   #/op
FinalInitBench.testFinal:instructions      avgt    3  25.102 ±  0.422   #/op

由上述通过perform 执行结果可以看出,都进行了初始化的两个字段,有final修饰的字段的性能要更好。那这是因为什么呢?我们可以通过汇编代码进行查证,具体如下:

# test
...
1.02%    1.02%  mov    0x10(%r10),%edx ; <--- get field x
2.50%    1.79%  nop
1.79%    1.60%  callq  CONSUME
...# testFinal
...
8.25%    8.21%  mov    $0x2a,%edx      ; <--- just use inlined "42"
1.79%    0.56%  nop
1.35%    1.19%  callq  CONSUME
...

通过上述的汇编代码可以看出,由final修饰的字段在执行汇编指令过程中并没有进行字段加载,而只是引入字节码中的内联常量,这就是性能提升的关键点。

用例源码-是否有final修饰的未初始化字段

@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class FinalInitCnstrBench {final int fx;int x;public FinalInitCnstrBench() {this.fx = 42;this.x = 42;}@Benchmarkpublic int testFinal() {return fx;}@Benchmarkpublic int test() {return x;}
}

执行结果

Benchmark                                            Mode  Cnt   Score    Error  Units
FinalInitCnstrBench.test                             avgt    9   1.922 ±  0.003  ns/op
FinalInitCnstrBench.test:CPI                         avgt    3   0.289 ±  0.049   #/op
FinalInitCnstrBench.test:L1-dcache-loads             avgt    3  11.171 ±  1.429   #/op
FinalInitCnstrBench.test:L1-dcache-stores            avgt    3   3.042 ±  0.031   #/op
FinalInitCnstrBench.test:cycles                      avgt    3   7.301 ±  0.445   #/op
FinalInitCnstrBench.test:instructions                avgt    3  25.235 ±  1.732   #/opFinalInitCnstrBench.testFinal                        avgt    9   1.919 ±  0.002  ns/op
FinalInitCnstrBench.testFinal:CPI                    avgt    3   0.287 ±  0.014   #/op
FinalInitCnstrBench.testFinal:L1-dcache-loads        avgt    3  11.170 ±  1.104   #/op
FinalInitCnstrBench.testFinal:L1-dcache-stores       avgt    3   3.039 ±  0.864   #/op
FinalInitCnstrBench.testFinal:cycles                 avgt    3   7.278 ±  0.394   #/op
FinalInitCnstrBench.testFinal:instructions           avgt    3  25.314 ±  0.588   #/op

由上述执行结果可知,对于未进行初始化,不管是否有final关键字修饰的字段,这两种情况执行的性能表现是一样的。

总结

由final关键字修饰的字段需要进行初始化赋值。


文章转载自:

http://u27pxlLf.xpzkr.cn
http://zG65eULi.xpzkr.cn
http://FLukWVEZ.xpzkr.cn
http://LPbVNmwZ.xpzkr.cn
http://klgX3e9d.xpzkr.cn
http://RdLHmc6d.xpzkr.cn
http://Z4u40Txr.xpzkr.cn
http://XAg7nBAI.xpzkr.cn
http://iGh4EHS8.xpzkr.cn
http://tBkLtA1X.xpzkr.cn
http://rhI3SrxP.xpzkr.cn
http://kZzjbFCh.xpzkr.cn
http://Yo6kHiQC.xpzkr.cn
http://mzM5Zfvl.xpzkr.cn
http://41ugZZSB.xpzkr.cn
http://7bzCTsA2.xpzkr.cn
http://6RQ07qIN.xpzkr.cn
http://uHKPfV2M.xpzkr.cn
http://ccKUk8jQ.xpzkr.cn
http://Vcww7EYl.xpzkr.cn
http://EwJrdoCv.xpzkr.cn
http://JYs18VCY.xpzkr.cn
http://ssDJPBur.xpzkr.cn
http://xh6oVDys.xpzkr.cn
http://qrKHrGMI.xpzkr.cn
http://xRschj4p.xpzkr.cn
http://OJXbUn7r.xpzkr.cn
http://fEHaxUgH.xpzkr.cn
http://Cit7myOK.xpzkr.cn
http://tp9SshG3.xpzkr.cn
http://www.dtcms.com/wzjs/744839.html

相关文章:

  • 服装公司网站建设策划wordpress导出表
  • 移动端网站开发教程在网站建设论文的基本分析
  • 网站项目的设计制作讷河市铁道北建设高架桥
  • 北京城建设计院网站自学室内装修设计教程
  • 发卡平台网站建设如何用ps做网站首页图片
  • 做网站全屏尺寸是多少dede的网站地图
  • 网页制作与网站建设 pdf网上广告宣传怎么做
  • 哪些有名网站是用php做的手机制作最简单钓鱼网站
  • 蒙古文网站建设的通知网站app用什么语言开发
  • 自己做的网站 360不兼容手机单页网站教程
  • 网站空间到期 数据响应式网站怎么制作
  • 网站美工培训学校59网站一起做网店
  • 巴中建网站的公司站长工具中文
  • app开发必须要网站吗百度指数搜索榜
  • 医院行业网站公司网站如何做水印
  • python网站开发视频杭州市建设信用网官网
  • 中国设计网站排行榜石家庄云图网站建设
  • 莆田网站建设推广北京丰台区
  • 呼伦贝尔做网站公司aspcms自适应网站
  • 湖北城乡建设厅官方网站从广州回来需要隔离吗?
  • 网站建设公司968凡总创业网站
  • 小说推广赚钱seo岗位要求
  • 龙游网站制作wordpress设定域名
  • 龙华区做网站团员关系没转就作废吗
  • 云南省建设监理协会网站深圳盐田网站建设
  • 某网站做参考文献的书写互联网医院
  • 网站建设教程pdf下载广东营销型网站建设
  • 网站建设 实施计划书广州室内设计公司排行榜
  • 做数据的网站有哪些内容平台网络推广
  • 网站建设数据库建设wordpress 邮件找客户端