A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 吴硕 中级黑马   /  2013-2-27 23:54  /  2609 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 吴硕 于 2013-2-28 17:22 编辑

final修饰的变量的生命周期以及内存位置?

编译器会预处理final修饰的变量吗?
在编译时期,代码中使用final修饰的变量的地方,是否在编译后已经被替换成了变量对应的值呢?

--------------------------------------------------------------------------
下面是我的理解,从网上看到的,不对的请指正

final修饰的变量对于变量的生命周期没有任何影响

编译器不全会预处理final修饰的变量
如下会预处理:
final int I1 = 9;
如下不会预处理:
final int I2 = (int)(Math.random()*20);

预处理针对基本数据类型,并且在定义变量时就可以确定值

4 个回复

倒序浏览
这是我在别人博客抄来的,觉得说不错!
定义为final后,编译程序的实现方法:将所有的局部内部类对象要访问的final型局部变量,都拷贝成为该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。(这一点我有些怀疑)

总结:局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。因此,正是在这个意义上,final型局部变量的生命期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量(含final)全死亡了。但:局部内部类对象中有final型局部变量的拷贝。
回复 使用道具 举报
final关键字对于变量的存储区域是没有任何影响的,生命周期和储存位置,是看它是什么性质的变量,
final修饰的变量有三种,静态变量、实例变量和局部变量,分别表示三种类型的常量。类的静态变量存储在方法区,实例变量存储在堆区,局部变量存在于栈中。
至于生命周期,静态是最长的,局部变量是最短的。
编译后当然替换成了变量对应的值,该值无法改变。
(第一次回答的这么有诚意,坛主你知道我什么意思。。。。。)
回复 使用道具 举报
曾经我在网上搜索收藏的笔记与你分享一下
用final修饰的变量最多只能赋值一次,在赋值方式上不同类型的变量或稍有不同:
1.静态变量必须明确赋值一次;作为类成员的静态变量,赋值可以在其声明中通过初始化表达式完成,也可以在静态初始化块中进行;
作为接口成员的静态变量,赋值只能在其声明中通过初始化表达式完成;
2.实例变量同样必须明确赋值一次;赋值可以在其声明中通过初始化表达式完成,也可以在实例初始化块或构造器中进行;
3.方法参数变量在方法被调用时创建,同时被初始化为对应实参值,终止于方法体(body)结束,在此期间其值不能改变;
4.构造器参数变量在构造器被调用(通过实例创建表达式或显示的构造器调用)时创建,同时被初始化为对应实参值,终止于构造器体结束,在此期间其值不能改变;
5.异常处理器参数变量在有异常被try语句的catch子句捕捉到时创建,同时被初始化为实际的异常对象,终止于catch语句块结束,在此期间其值不能改变;
6.局部变量在其值被访问之前必须被明确赋值;
final关键字对于变量的存储区域是没有任何影响的。
类的静态变量存储在方法区,实例变量存储在堆区。static关键字才是对变量的存储区域造成影响的。
版主老大,压箱底都掏出来了,赐一分吧
回复 使用道具 举报
final使得被修饰的变量"不变",但是由于对象型变量的本质是“引用”,使得“不变”也有了两种含义:引用本身的不变,和引用指向的对象不变。
可以一下方法验证

  引用本身的不变:
  final StringBuffer a=new StringBuffer("immutable");
  final StringBuffer b=new StringBuffer("not immutable");
  a=b;//编译期错误

  引用指向的对象不变:
  final StringBuffer a=new StringBuffer("immutable");
  a.append(" broken!"); //编译通过

所以有此可见
final只对引用的“值”(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,
改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。

所以 final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马