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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李建强 中级黑马   /  2012-9-25 20:51  /  4023 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李建强 于 2012-9-25 20:54 编辑

  1. class Test
  2. {
  3. public static void main(String[] args)
  4. {
  5.   final StringBuffer sb=new StringBuffer("我是final的,不要改变我。"); //执行如下语句将报告编译期错误:
  6.   //sb=new StringBuffer("我试试能改不。"); //这一行编译失败。
  7.   sb.append(" 不好意思,已经改变了。"); //编译成功
  8.   System.out.println(sb.toString());
  9. }
  10. }
  11. //输出结果为:我是final的,不要改变我。不好意思,已经改变了。
  12. //这样看来final也是可以被改变的。
  13. //怎么样才能不被改变?
复制代码

7 个回复

倒序浏览
//输出结果为:我是final的,不要改变我。不好意思,已经改变了。
//这样看来final也是可以被改变的。
//怎么样才能不被改变?

LZ你的理解是不正确,首先执行到sb.append(" 不好意思,已经改变了。"); 这句话的时候,
是字符串 " 不好意思,已经改变了。" 追加到这个字符串缓冲区中, 将是返回了这个对象
的一个引用
,并非是改变了 sb字符串缓冲区, 所以fina 修饰的 普通变量或者是引用型变量都是
不可以改变的。
回复 使用道具 举报

final_png.png (9.29 KB, 下载次数: 59)

final_png.png

评分

参与人数 2技术分 +3 收起 理由
admin + 2 我要表示严重的奖励
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
1.final关键字可以被加到类的声明中,final类是不允许继承的;
2.final关键字可以被加到方法声明中,final方法是不允许重写的(override),这个效果同私有方法一样;
3.final关键字可以被家到属性或者变量的声明中,final属性或者变量一旦赋值之后就不允许再发生变化。对于基本类型(primitive type),比如int、double、long、byte等,一旦被生命为final,我们就可以将其当作常量来看待,但是对于引用类型或者数组(数组在java中也是对象)来说,则不是。虽然一个引用类型被赋值之后无法发生变化,但是我们仍然可以修改被引用的那个对象或者数组中的元素。因此在java中,常量的定义与其他语言相比可能会有点差异,在java中,常量的定义是:被声明为final的基本类型或者是通过编译时常量初始化的String类型;
4.方法的参数可以被声明为final,这些参数一旦初始化之后,在方法体中是不能改变其值的。基本上,在接口中将方法参数声明为final是没有什么意义的,因为java的编译器并没有强制要求在继承接口时,方法的参数也一定要带上final。也就是说,一个方法的参数是否为final并没有被当成是方法签名中的一部分,这个对于类的继承也是一样的。关于这一点,大家可以写个简单的程序测试一下;
5.本地类的方法中只能使用final类型的本地变量;
6.通常情况下,将方法或者变量生命为final类型有助于提高程序运行时的性能;

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
程振 发表于 2012-9-25 21:10

3楼的意思是不是:sb是StringBuffer类对象的引用,指向内存中的地址是不可被改变的。
但是sb指向的对象内容还是改变了,与我的期望不同。
怎么样能使对象内容不变?
回复 使用道具 举报
要区分对象的引用值和对象的属性值,在这里,LZ你是用final修饰引用型变量,那么这个变量是不可以再指向其他变量了(就是说不能再new StringBuffer了),而它的值是可以改变的,我的理解是这样。
回复 使用道具 举报
本帖最后由 叶征东 于 2012-9-25 21:25 编辑

final修饰的是sb这个对象,不是sb中的内容,
这也就是为什么
sb=new StringBuffer("我试试能改不。"); //这一行编译失败。
sb.append(" 不好意思,已经改变了。"); //编译成功
更深层的原因是final使sb在内存中的地址值不能被改变(我的理解).

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
final定义过的当然不能修改了,只是对于有些情况,需要理解清楚,比如StringBuffer
final定义为:对于基本类型,final使数值恒定不变,但是而对于对象引用,fina只是l使引用不变而已
一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。
但是明显可以知道,对象其自身却是可以被修改的,Java并未提供使任何对象恒定不变的途径。
比如final Person p =new Person();
p.name="new";//这句话是可以通过编译的,因为引用本身没变,依然指向那儿,只是对象的属性改变了而已

而StringBuffer.append(String str)也是这个道理,它使引用没有改变,只是使引用指向的对象增加了而已
API中这样说的:按顺序追加 String 变量中的字符,使此序列增加该变量的长度 所以可以看出,引用一直没变过
希望能解决楼主的问题。

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马