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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© cvnmklop 中级黑马   /  2014-11-17 20:09  /  1428 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 cvnmklop 于 2014-11-17 22:09 编辑

无意之中看到一段代码
  1. public class TTT {
  2.         public static void main(String[] args) throws Exception {
  3.                 for (int i = 0; i < 10; i++) {
  4.                         final String threadId = "thread_" + i;
  5.                         Thread thread = new Thread(new Runnable() {
  6.                                 public void run() {
  7.                                         System.out.println(threadId + " started!");
  8.                                         try {
  9.                                                 FileInputStream fis = new FileInputStream("/opt/test.log");
  10.                                                 Thread.sleep(60 * 1000);
  11.                                         } catch (Exception ex) {
  12.                                                 ex.printStackTrace();
  13.                                         }
  14.                                         System.out.println(threadId + " stopped!");
  15.                                 }
  16.                         });
  17.                         thread.start();
  18.                 }
  19.                 Thread.sleep(10 * 60 * 1000);
  20.         }
  21. }
复制代码
有没有觉得有疑惑?是的正是这一句final String threadId = "thread_" + i;太diao了。
于是乎我就自己去验证了,验证代码如下
  1. class FinalDemo{
  2.         public static void main(String[] args){
  3.                 for(int i=0;i<10;i++){
  4.                         final String str = "number_"+i;
  5.                         System.out.println(str);
  6.                 }
  7.         }
  8. }
复制代码

打印结果来了
number_0
number_1
number_2
number_3
number_4
number_5
number_6
number_7
number_8
number_9
那就怪了我们都知道final的用法
1、修饰类,类不能被继承 2、修饰方法,方法不能被覆盖  3、修饰变量,变量只能赋值一次。即基本数据类型值不变。引用类型其引用不变
要知道字符串拼接是生成新的字符串的。有人可能会说这个拼接字符串的地址没变只是i的值在变化。
那好我就再换个方法验证,代码如下
  1. class FinalDemo{
  2.         public static void main(String[] args){
  3.                 for(int i=0;i<10;i++){
  4.                         final  Object str = new Object();
  5.                         System.out.println(str);
  6.                 }
  7.         }
  8. }
复制代码

打印结果如下
java.lang.Object@15db9742
java.lang.Object@6d06d69c
java.lang.Object@7852e922
java.lang.Object@4e25154f
java.lang.Object@70dea4e
java.lang.Object@5c647e05
java.lang.Object@33909752
java.lang.Object@55f96302
java.lang.Object@3d4eac69
java.lang.Object@42a57993

这下看到了吧。连引用改变都是可以的。

现在问题来了这是为什么呢?
难道final修饰的局部变量的值可以改变?还是这个final是限定其他的?  坐等高手。






评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 淡定

查看全部评分

5 个回复

正序浏览
楼上正解~
回复 使用道具 举报
DamonZh 来自手机 中级黑马 2014-11-18 13:44:00
报纸
定义和赋值是不一样的 你这是在每一次循环定义一个新的变量 而不是给变量赋值
回复 使用道具 举报
杨佳名 发表于 2014-11-17 23:28
这个是for循环变量定义问题,而不是final问题.之前理解的final并没有错
以写代码时,尽量在for循环外定义变 ...

我刚开始也是这么想的,所以看得懂。就是一个循环,代表了一个变量
回复 使用道具 举报
李运岚 发表于 2014-11-17 20:23
同求回复啊,高手呢

这个是for循环变量定义问题,而不是final问题.之前理解的final并没有错
以写代码时,尽量在for循环外定义变量;
定义在内部,每一次循环都在堆栈中分配空间,每一次结束时,定义的变量都被回收
也就是说,你所想的 final String str = "number_"+i;  在循环中并不是一个str
有些啰嗦,没组织好语言:L
回复 使用道具 举报 1 0
同求回复啊,高手呢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马