Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 340|回复: 0

[Java基础知识]java中final的用法与效率

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-9-30 17:44:03 | 显示全部楼层 |阅读模式
    一 概念
        在java中, 可以使用final关键字修饰类、方法以及成员变量。

    1 final标记的类不能被继承
        在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。

    2 final标记的方法不能被子类重写
    ① 把方法锁定,防止任何继承类修改它的意义和实现
    ② 高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率

    3 final标记的变量即成为常量,只能被赋值一次

    二 用法

    1 对于引用类型和值类型来说
       final的变量一旦被赋值,就不能再此改变。但对于引用类型,其“不可改变”的是指其地址不能改变而其属性可以改变。   
      
       
       

         
       

         
       
      


    2 对于成员变量和局部变量来说
    对于final的成员变量,对其赋值有两种方式:① 声明时即赋值;②构造方法中赋值。
    对于final的局部变量,对其赋值有两种方式:①声明时即赋值;②使用的时候赋值。

    例子一

    1. public class Test
    2. {
    3. final int a;
    4. final int b = 0;//声明时赋值
    5. public Test()
    6. {
    7.   a = 0;
    8.   // b = 1;//编译不能通过
    9. }
    10. public Test(int i)
    11. {
    12.   a = 1;
    13. }
    14. public static void printFinal()
    15. {
    16.   final int m = 100;
    17.   // m = 101;//编译不能通过
    18.   final int n;
    19.   n = 102;
    20.   // n = 103;
    21.   System.out.println("m + n=" + m + n);
    22. }
    23. }

    24. 例子二
    25. import cn.xy.model.Person;
    26. public class Test2
    27. {
    28. final Person p = new Person("xy");
    29. final Person p2;
    30. public Test2()
    31. {
    32.   p2 = new Person("xy");
    33.   p.setName("xyy");
    34.   // p = new Person("Jim");//编译不能通过
    35.   // p = null;
    36. }
    37. public Test2(int i)
    38. {
    39.   p2 = new Person("xy");
    40. }
    41. public static void printFinal()
    42. {
    43.   final Person p = new Person("xy");
    44.   p.setName("xyy");
    45.   // p = new Person("Jim");
    46.   // p = null;
    47. }
    48. }

    49. 3 关于final修饰类和方法的例子这里不举例,读者可以试一试。

    复制代码
    三 final内存分配

        调用一个函数除了函数本身的执行时间之外,还需要时间去寻找这个函数(类内部有一个函数签名和函数地址的映射表)。故减少函数调用次数就等于降低了性能消耗。final修饰的函数会被编译器优化,优化的结果是减少了函数调用的次数。

    1. public class Test3
    2. {
    3. final void function()
    4. {
    5.   System.out.println("xy");
    6. }

    7. public static void main(String[] args)
    8. {
    9.   Test3 t = new Test3();
    10.   for(int i = 0;i< 1000;i++)
    11.   {
    12.    t.function();
    13.   }
    14. }
    15. }

    16. 经过编译器优化之后,这个类变成了相当于这样写:
    17. public class Test3
    18. {
    19. final void function()
    20. {
    21.   System.out.println("xy");
    22. }

    23. public static void main(String[] args)
    24. {
    25.   Test3 t = new Test3();
    26.   for(int i = 0;i< 1000;i++)
    27.   {
    28.    System.out.println("xy");
    29.   }
    30. }
    31. }
    复制代码
    优点:
       编译器直接将function的函数体内嵌到了调用函数的地方,这样的结果是节省了1000次函数调用,当然编译器处理成字节码,只是我们可以想象成这样,看个明白。

    缺点:
       当函数体若太长时用final会适得其反,因为经过编译器内嵌之后代码长度大大增加,于是就增加了JVM解释字节码的时间。而且如果final修饰的方法体过大的话,编译器可能会放弃内联。



      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-20 17:02 , Processed in 0.362629 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表