每个初学者都应该搞懂的问题(4)

alienbat 2004-03-23 07:54:35
对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。


final关键字到底修饰了什么?
要理解此问题,请首先理解本系列第二个问题所阐述的概念。http://expert.csdn.net/Expert/topic/2868/2868492.xml?temp=.3966181

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问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它“永远不变”。其实那是徒劳的。


...全文
734 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzlouiszz 2004-09-25
  • 打赏
  • 举报
回复
精彩,很久没看来这样的辩驳了,谢谢大家,“大家”,我是小菜,
别看我无级无星,我搞计算机编程的年龄也不短了,大家用过apple2的8088没,那时我还没听过OO呢,看来现在的技术是比那个年代复杂多了,我的QQ:27382077,我一般不上CSDN,就只有个号吧了,还是别人叫我申请的也,想交流加我,菜的不加
ben512 2004-09-23
  • 打赏
  • 举报
回复
感谢各位精辟的分析~
kinglds 2004-09-19
  • 打赏
  • 举报
回复
up
takecare 2004-09-13
  • 打赏
  • 举报
回复
哈哈,alienbat (亡灵法师) 你也可以现身了,很多人在怀念你噢!
power0811 2004-09-13
  • 打赏
  • 举报
回复
谢谢楼主,你的每个问题我都看了,我是个初学者,获益不少哦.thanks^_^
takecare 2004-09-13
  • 打赏
  • 举报
回复
同意 flyforlove(为情飞)的分析!

private是oo设计层面上的东西,告诉使用者信息。
而final则是在编译的层面上的,它是无视那些访问修饰符的。
heibai520 2004-09-13
  • 打赏
  • 举报
回复
gz
Eddie 2004-09-10
  • 打赏
  • 举报
回复
gz
flyforlove 2004-09-10
  • 打赏
  • 举报
回复
private关键字也有这个不能被子类继承的意思。那么问题出来了那么我是不是应该把所有private的方法也都定义成final的呢?
例如:
public class A {
private final methodA() {
....
}
}

-------------------------------------------------------------

这还是有区别的,如果只是一个private的话,虽然不能继承,但是子类是可以声明相同方法的。比如:
public class A {
private void methodA() {
....
}
}
public class B extends A{
private void methodA() {
....
}
}

但是如果加上final的话,在这样写就不对了。
takecare 2004-09-09
  • 打赏
  • 举报
回复
对了,看到 Sheepy(-[J.2.E.E]-) 的补充:“final不能子类被继承”,让我联想到另外一个关键字private。

来搞脑子,把这水搅混吧。哈哈。

private关键字也有这个不能被子类继承的意思。那么问题出来了那么我是不是应该把所有private的方法也都定义成final的呢?
例如:
public class A {
private final methodA() {
....
}
}
takecare 2004-09-09
  • 打赏
  • 举报
回复
亡灵虽然比较刻薄,但是总结的一些内容还是不错的。
gyang 2004-09-09
  • 打赏
  • 举报
回复
aa
HITZXL 2004-08-28
  • 打赏
  • 举报
回复
又看了楼主的其它帖子,
我觉得如果对不可变(immutable)类的对象实行final声明
那一定能达到引用本身的不变,和引用指向的对象不变。
比如String
shine333 2004-08-28
  • 打赏
  • 举报
回复
TO 亡灵:

有一点可能需要指正

>这很类似==操作符:==操作符只负责引用的“值”相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。

我的理解是==操作符只负责a == b,不负责a.x == b.x;

但是如果a == b, a.x可能!= b.x吗?

不知道这样的理解对吗?

TO HITZXL(编程要厚道) :
>所以对于对象使用final根本就是无意义的吧!

当然有意义了,匿名内部类应该写过吧?

从生命周期来讲,匿名内部类所用到的方法中的局部变量的生命周期延长了
HITZXL 2004-08-27
  • 打赏
  • 举报
回复
看到楼主和: Sheepy(-[J.2.E.E]-) 的帖子
受益颇深
可还有个问题
就是
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
这里的final声明的应该是对象a和对象b是不可变得意思吧/
这个对象的不可变性,是什么意思
按我的理解,应该是指对象的起始地址不变,通俗点讲,就是对象的门牌号永远不变
而StringBuffer是设定成对象分配的内存容量是可变的,内容也是可变的
而所有的对象都没有因为一个final,把对象所占的那块内存设置成只读的
所以对于对象使用final根本就是无意义的吧!
请继续讨论
HITZXL 2004-08-27
  • 打赏
  • 举报
回复
呵呵!楼主威名远播了~
-------
不过帖子还是很值得看的
WuLoveXue 2004-04-28
  • 打赏
  • 举报
回复
哎呀,我是从水园里慕名来看望楼主的!
不过,看到楼主在教初学者这种问题,大跌眼镜了!
appleangle 2004-04-25
  • 打赏
  • 举报
回复
学习
youngby 2004-04-25
  • 打赏
  • 举报
回复
我来拜神了~~~!~

楼主好厉害~!~

在CSDN上,偶有个偶象,C++区的111222,他呀,
也是个低学历的,没有读大学,
今年也才22岁,是
“MP3音乐猎手”的作者。


http://www.111222.cn/

111222,年纪没有你大,学历没有你大,家境没有你好,
好象也是你鄙视的那一种吧,`1

不知道,楼主贴过几个共享软件?

SHIT~!~


==========================================
楼主呀。有钱人,也鄙视偶一下吧。偶没有读大学,也是22岁,工作三年了。
MD,现在还是垃圾一个,
最近还失恋爱了~!

http://expert.csdn.net/Expert/TopicView1.asp?id=2999739

===========================================

Sheepy 2004-04-25
  • 打赏
  • 举报
回复
To:youngby(诗人)(我~叫黄晨~、烦烦~烦~、烦~)

不说说你你还真会洋洋得意以为自己说得有道理人家都服了你了没话说了。一看你就是不懂Java或者自以为懂实际上不懂的人。你拿来一块不锈钢,说:
“你这个窗帘也不见得比这块不锈钢好么。SHIT~!~”
加载更多回复(9)

62,612

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧