⑴ java方法中变量用final修饰对性能有影响!你觉得呢
在java中使用final修饰类型(包括类和接口)或类的成员与修饰方法中的普通变量从JVM的角度上看是不一样的!鉴于你谈论的是用其修饰方法中普通变量的形式,故简单说一下这方面的东东。
是否使用final修饰方法中普通变量对JVM来说没有区别!使用final修饰方法中普通变量主要是为了给Java前端编译器(如javac)看的!也就是说方法中被final修饰的普通变量在前端编译时被javac检查并保证该变量不会在作用域内被改变新值,但被编译成字节码后用于修饰方法中普通变量的final就已经不存在了!说的再具体点就是你用或不用final修饰方法中普通变量而生成的字节码文件(.class文件)没有区别(建议你用某种Class文件编辑器查看一下)!!! 当然在编译过程中会扫描final关键字并对其生成词法单元(Token),同时生成的抽象语法树(AST)在未优化之前也是有区别的。
故如你所说的“普通方法中变量用final修饰的,方法结束后jvm是不会回收这个变量的,也就不会释放内存!”这个要看该变量的作用域(比如是否发生常见的方法或线程逃逸等情况)以及是否赋值为字面量(比如字符串字面量"XXX"在加载时会被拘留(intern)在运行时常量池中,而不会在方法结束后下次GC时被回收,但这与final修饰无关!) 等特殊情况,但其是否被回收与是否仅被final修饰无关!!
至于用final修饰类型(包括类和接口)或类的成员从JVM角度考虑就和上面的很不一样了,比如你谈到的被final修饰的方法,虽然从虚拟机规范层面上讲也使用invokevirtual字节码调用,但其实它已经属于非虚方法,在JVM的角度上完全可以(当然还要看具体JVM如何实现)用指向目标方法对象的指针来作为解析的结果(直接引用),而不用再通过虚方法表进行每次执行时的动态分派过程,从而提高运行效率。再比如你谈到的内联,就我所知不用final修饰的方法在运行时只要JVM判断其满足一定条件(比如常见的HotSpot虚拟机对“热点”方法的判断)时也会根据具体情况进行内联(守护内联机制或内联缓存机制)这种基础优化机制,这方面就不多说了。(有些跑题了,呵呵)
最后想说的就是不推荐仅为了有可能提高的一点执行效率而尽可能多的使用或者滥用final(同样也适用于static等关键字),首先提升程序执行效率应该更多的从算法复杂度、业务流程合理性、软件架构合理性以及后期运行时环境调优上着手,而仅从某种语法内部运行机制上打主意意义不大!当然《Effective Java》中还是给出了不少关于使用java方面有意义的指引。其次不同的JVM产品或相同JVM产品不同版本或相同版本不同JVM配置参数都可能对同一语法机制在内部有不同的运行策略,很有可能原本希望提升执行效率的手段在某种运行时环境下却成了瓶颈。再者就算不考虑代码的可读性和可维护性,但在注释时又如何去说明仅为了提升性能而用的final或其他关键字呢?(当然可以忽视掉对它们的注释,我想这也是造成楼主提问的原因。)
罗嗦了一大堆,也不知是否是你想谈论的,希望对彼此有帮助吧。
个人看法,属于原创,仅供参考,水平有限,错误难免,接受指正,谢谢。
⑵ Java中final修饰的类有什么作用
Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用法。x0dx0a1.修饰类x0dx0a当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。x0dx0ax0dx0a在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。x0dx0a2.修饰方法x0dx0a下面这段话摘自《Java编程思想》第四版第143页:x0dx0a“使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。“x0dx0a因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。x0dx0a注:类的private方法会隐式地被指定为final方法。x0dx0a3.修饰变量x0dx0a修饰变量是final用得最多的地方,也是本文接下来要重点阐述的内容。首先了解一下final变量的基本语法:x0dx0a对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
⑶ Java给函数的参数加上final,对性能有影响吗
可以提高性能,但是非常少,使用FINAL把变量定义为常量之后,一定程度上加快了变量的读取,因为你肯定不会也不可能再修改了,所以虚拟机对常量会采取特殊存储优化。
⑷ 如何优化JAVA代码及提高执行效率
1、 尽量指定类的final修饰符带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了人们覆盖length()方法。另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50% 。
2、 尽量重用对象。特别是String 对象的使用中,出现字符串连接情况时应用StringBuffer 代替。由于系统不仅要花时间生成对象,以后可能还需花时间对这些对象进行垃圾回收和处理。因此,生成过多的对象将会给程序的性能带来很大的影响。
3、 尽量使用局部变量,调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化。请参见《尽可能使用堆栈变量》。