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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 弘一 中级黑马   /  2013-12-14 08:19  /  1718 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

使用final修饰后的变量不是应该不能够修改的吗?
class Demo
{
        public static void main(String[] args)
        {
                 final Student s = new Student();
                 s.setName("asw");
        }
}
我为什么还能够通过Student的setName方法来修改Student的name属性?

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

6 个回复

倒序浏览
class Demo
{
         public static void main(String[] args)
         {
                  final Student s = new Student();
                  s.setName("asw");
         }
首先,final修饰过的是引用型的变量s,即s具体指向就是当前创建的这个对象,不能改变的是s指向的对象,而对象的属性还是可以改变的。如果要使对象的属性值定义成常量,则应该在对象所对应的类中的属性用final修饰。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
final Student s = new Student();
是指:引用变量s的,内存地址不会在改变,也就是说s不会,从新指向一个新的Student对象或其子类。
s.setName("asw");
如果这句不能执行,需要对Student这个JavaBean内部的name属性修饰final,赋初始值,才可以这时就不可以在通过set方法赋值。

18、final关键字(重点)
        (1)最终的意思,可以用于修饰类,方法,变量。
        (2)final修饰的类不能被继承。
           final修饰的方法不能被重写。
           final修饰的变量是一个常量。只能被赋值一次。
           内部类只能访问被final修饰的局部变量。


回复 使用道具 举报
25343215 发表于 2013-12-14 08:50
final Student s = new Student();
是指:引用变量s的,内存地址不会在改变,也就是说s不会,从新指向一个 ...

楼上说的很详细啊,简单说就是final修饰谁,谁就不能变。
final Student s 修饰的是Student类型的引用变量s,所以s的指向是不能变的,而s指向的对象是可以变的,这回明白了吧。
回复 使用道具 举报
final修饰代表最终,不可更改,修饰变量时,代表常量。
而你这里的变量s是一个引用类型,意思是指向你new Student()的这个内存地址不会改变
你的问题出在内存分析当中,当你new一个对象的时候,并不是变量存储了对象,而是变量存放于栈内存中,然后指向了对象所在的堆内存地址。当你去利用对象的方法操作数据时,你并不是更改了s这个存在于栈内存的数据,而是更改了你new的那个对象。
所以这里你的理解错误了,变量s从头到尾都是在指向new Student()这个对象,并没有更改

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
Y_Y 中级黑马 2013-12-14 09:52:03
地板
final方法
将方法声明为final,那就说明你已经知道这个方法提供的功能已经满足你要求,不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也就是说可以直接使用。另外有一种被称为inline的机制,它会使你在调用final方法时,直接将方法主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使你的程序效率有所提高,然而当你的方法主体非常庞大时,或你在多处调用此方法,那么你的调用主体代码便会迅速膨胀,可能反而会影响效率,所以你要慎用final进行方法定义。

final类
当你将final用于类身上时,你就需要仔细考虑,因为一个final类是无法被任何人继承的,那也就意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要进行修改或扩展。对于final类中的成员,你可以定义其为final,也可以不是final。而对于方法,由于所属类为final的关系,自然也就成了final型的。你也可以明确的给final类中的方法加上一个final,但这显然没有意义。

评分

参与人数 1技术分 +1 收起 理由
乔兵 + 1

查看全部评分

回复 使用道具 举报
楼上解释很详细,受教了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马