黑马程序员技术交流社区

标题: 使用final关键字修饰一个变量时,是引用不能变还是引用的... [打印本页]

作者: 阳丹    时间: 2013-6-6 23:53
标题: 使用final关键字修饰一个变量时,是引用不能变还是引用的...
本帖最后由 阳丹 于 2013-6-7 22:42 编辑

使用final关键字修饰一个变量时,是引用不能变还是引用的对象不能变???
作者: 李征    时间: 2013-6-7 00:07
是指引用变量不能变,引用变量所指向的对象中的内容可以变。这个问题我在哪看到过,挺熟悉的感觉
作者: 山鹰    时间: 2013-6-7 00:08
被final修饰的变量是常量  常量不可以改变引用和相对应的值都不能改
作者: 胡晓思    时间: 2013-6-7 00:11
使用final关键字修饰的一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.
例如:
  1. final StringBuffer a = new StringBuffer("init");
复制代码
执行如下语句将报告编译期错误:
  1. a = new StringBuffer("");
复制代码
但是,执行如下语句则可以通过编译:
  1. a.append("nihao!");
复制代码

作者: 王林涛    时间: 2013-6-7 00:20
哥们儿先给你说下final关键字是作用,你看了就懂了!如果不懂,记住就行!
1,可以修饰类,函数,变量
2,被final修饰的类不可以被继承.为了避免被继承,被子类复写功能。
3,被final修饰的方法不可被覆写
4,被final修饰的变量是一个常量,只能赋值一次。既可以修饰成员变量,也可以修饰局部变量。
   当在描述事物时,一些数据的出现,值是固定的。那么这时为了增强阅读性,都给这些值起个名字。方便阅读。
   而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果多个单词组成,单词通过_连接。
5,内部类定义在类中的局部位置上时,只能访问该局部被final修饰的局部变量。
作者: 张歆明    时间: 2013-6-7 20:24
**********************************************************
使用final关键字修饰一个变量时,是引用不能变还是引用的对象不能变???
**********************************************************
无论final修饰什么变量  它的值都是不能改变的。
对于基本数据类型  你应该很了解了  所以 不说了

现在 你不理解的地方主要是在引用和它指向的对象的问题吧:现在以下面的为例子:
(1). 引用变量demoA 是存在于栈内存中的  它的值是new DemoA()在堆内存中开辟的对象的地址
这时候 试图改变这个demoA中的地址值 也就是想重新让demoA指向新的对象:
final DemoA demoA=new DemoA();

demoA =new Demo();


编译出错
*******************************************
D:\BlackHorse_Pro\IO>javac DemoA.java
DemoA.java:7: 错误: 无法为最终变量demoA分配值
                demoA =new Demo();
                ^
DemoA.java:7: 错误: 不兼容的类型
                demoA =new Demo();
                       ^
  需要: DemoA
  找到:    Demo
2 个错误
*******************************************
所以  引用也是变量  被final修饰之后 里面的值和基本数据类型的变量是一样的 不能被再改变

但是 demoA指向的对象是不能变了(只能指向这个对象)  但是 由于对象里面也有变量  此时 如果类中的成员没有被final修饰  还是可以改变里面的值得
  1. public class DemoA
  2. {
  3.         public int a;
  4.         public DemoB demoB;
  5.         public static void main(String[] args){
  6.                 final DemoA demoA=new DemoA(); //demoA的值不能被改变
  7.                 demoA.a =10;//demoA指向的对象的成员是可以改变的
  8.                 demoA.demoB =new DemoB();//同理
  9.                 System.out.println("demoA的地址:"+ demoA+"----成员a的值:"+ demoA.a);//demoA的地址:DemoA@19836ed
  10.                 System.out.println("demoA的地址:"+ demoA+"----成员demoB的地址值:"+ demoA.demoB);
  11.                 demoA.a =5;
  12.                 demoA.demoB =new DemoB();
  13.                 System.out.println("demoA的地址:"+ demoA+"----成员a的值:"+ demoA.a);//demoA的地址:DemoA@19836ed
  14.                 System.out.println("demoA的地址:"+ demoA+"----成员demoB的地址值:"+ demoA.demoB);
  15.         }
  16. }
  17. class DemoB{}
复制代码
测试结果
***********************************************************************
D:\BlackHorse_Pro\IO>javac DemoA.java

D:\BlackHorse_Pro\IO>java DemoA
demoA的地址:DemoA@19836ed----成员a的值:10
demoA的地址:DemoA@19836ed----成员demoB的地址值:DemoB@3e0ebb
demoA的地址:DemoA@19836ed----成员a的值:5
demoA的地址:DemoA@19836ed----成员demoB的地址值:DemoB@39443f

***********************************************************************

结论  栈内存中的引用变量和普通的基本类型的变量的值是一样的 只要被final修饰  就不能被改变
只不过  引用类型的变量的值有特殊的含义:就是表示堆内存中的对象的地址  由于引用变量的值(对象的地址)不能被改变  这就代表着指向的对象不能被改变
但是  虽然引用指向的对象不能被改变  但是这个对象本身和final没关系 它里面的成员如果不被final修饰  是可以被修改的



作者: 黑马伍哲沂    时间: 2013-6-7 21:15
如果 问题已经得到解决,请记得将帖子更为以解决。

提问和答题一些参考:http://bbs.itheima.com/thread-54900-1-1.html
作者: 张歆明    时间: 2013-6-7 21:55
黑马伍哲沂 发表于 2013-6-7 21:15
如果 问题已经得到解决,请记得将帖子更为以解决。

提问和答题一些参考:http://bbs.itheima.com/thread-5 ...

谢谢您给我评分 嘿嘿
作者: 阳丹    时间: 2013-6-7 22:20
胡晓思 发表于 2013-6-7 00:11
使用final关键字修饰的一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.
例如: ...

易于理解啊




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2