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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© yong230 中级黑马   /  2013-1-29 17:37  /  1896 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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,意图使得它“永远不变”。其实那是徒劳的。

评分

参与人数 1黑马币 +6 收起 理由
Rancho_Gump + 6

查看全部评分

8 个回复

倒序浏览
值得学习ing!
回复 使用道具 举报
顶一个 。
回复 使用道具 举报
想让东西不能被改变,就彻底封装起来,或者枚举,或者单例设计模式
思路是这样吧?
回复 使用道具 举报
杨浩 发表于 2013-2-1 22:10
想让东西不能被改变,就彻底封装起来,或者枚举,或者单例设计模式
思路是这样吧? ...

想要彻底让一个对象不能被改变,那么把属性私有,只提供公共的get方法,不要提供设置方法。
回复 使用道具 举报
黄锦成 发表于 2013-2-1 23:24
想要彻底让一个对象不能被改变,那么把属性私有,只提供公共的get方法,不要提供设置方法。 ...

暴力反射能破不?
要完全的封装起来,具体怎么做呢。
今天面试的时候,其实说道了这个地方,我说了暴力反射,老师告诉我说反射不是万能,后面学习框架就知道咯
嘛,肯定不能什么都破,要不然Java就没安全可言咯。
回复 使用道具 举报
杨浩 发表于 2013-2-1 23:37
暴力反射能破不?
要完全的封装起来,具体怎么做呢。
今天面试的时候,其实说道了这个地方,我说了暴力反 ...

反射不是万能的。如果别人使用了一些保护措施,就暴力破解不了。
下面这段话我是从core java那里看到的:
反射机制的默认行为受限于java的访问控制。然后,如果一个java程序没有受到安全管理器的控制,就可以覆盖访问控制。为了达到这个目的,需要调用Field、Method或Constructor对象的setAccessible方法。
回复 使用道具 举报
一、Java中final修饰符既可以修饰类、方法,也可以修饰变量,基本规则如下:
1)用final修饰的类不能被扩展,也就是说不可能有子类;
2)用final修饰的方法不能被替换或隐藏:
  ①使用final修饰的实例方法在其所属类的子类中不能被替换(overridden);
  ②使用final修饰的静态方法在其所属类的子类中不能被重定义(redefined)而隐藏(hidden);
3)用final修饰的变量最多只能赋值一次,在赋值方式上不同类型的变量或稍有不同:
  ①静态变量必须明确赋值一次(不能只使用类型缺省值);作为类成员的静态变量,赋值可以在其声明
   中通过初始化表达式完成,也可以在静态初始化块中进行;作为接口成员的静态变量,赋值只能在其
   声明中通过初始化表达式完成;
  ②实例变量同样必须明确赋值一次(不能只使用类型缺省值);赋值可以在其声明中通过初始化表达式
   完成,也可以在实例初始化块或构造器中进行;
  ③方法参数变量在方法被调用时创建,同时被初始化为对应实参值,终止于方法体(body)结束,在此
   期间其值不能改变;
  ④构造器参数变量在构造器被调用(通过实例创建表达式或显示的构造器调用)时创建,同时被初始化
   为对应实参值,终止于构造器体结束,在此期间其值不能改变;
  ⑤异常处理器参数变量在有异常被try语句的catch子句捕捉到时创建,同时被初始化为实际的异常对象
   ,终止于catch语句块结束,在此期间其值不能改变;
  ⑥局部变量在其值被访问之前必须被明确赋值;
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马