黑马程序员技术交流社区

标题: 关于String类的小问题 [打印本页]

作者: yemenglin    时间: 2014-5-8 21:33
标题: 关于String类的小问题
今天在遇到一个小问题,String类代表字符串,它被final修饰了,字符串就是常量了,是不可变的
class StringDemo{
     public static void main(String[] args){
          String str = "abcdefg";
          str = str.substring(0,3);
          System.out.println(str);
     }
}
为什么打印出来的结果不是abcdefg?  
作者: 时光♪微凉    时间: 2014-5-8 21:40
你这里不是没被final修饰吗?
  1. class StringDemo{
  2.      public static void main(String[] args){
  3.           String str = "abcdefg";
  4.           str = str.substring(0,3);//这里又重新给str赋值,结果怎么可能是abcdefg,如果上面有final修饰,那么这里会编译失败的
  5.           System.out.println(str);
  6.      }
  7. }
复制代码

作者: 轻语。    时间: 2014-5-8 22:13
你这里是str指向的内容不再是abcdefg字符串了,被重新赋值了。 而abcdefg字符串还是存在,还是不变的。认真看视频,里面都有的。

作者: jsjchenlong    时间: 2014-5-8 23:03
请看我下面的代码,希望对你的理解有帮助

        public static void main(String[] args) {
                 String str = "abcdefg";
                 //System.out.println(str);
         //str = str.substring(0,3);
                //这里的输出结果为”abcdefg“这个没有疑问吧
         System.out.println(str);
       //这里的输出结果为”abc“这个也没有疑问吧,这里其实会生成一个对象,不过随着代码执行完成也就消失了,你可以理解为匿名的对象
         System.out.println(str.substring(0,3));
       //这里的输出结果为”abcdefg“,我写这句代码是为下面做铺垫,想要告诉你的是,它还是原来的str。
         System.out.println(str);
         //这里的输出结果为”abc“,是因为在堆中生成了一个存储”abc“的空间,并且它把原来的str的地址给覆盖了,所以str指向的是一个新的地址
         System.out.println((str=str.substring(0,3)));
         //那这里输出的结果也自然是指向新地址存放的值得位置了,那么自然就是”abc“了
         System.out.println(str);
        }


作者: yemenglin    时间: 2014-5-9 22:05
时光♪微凉 发表于 2014-5-8 21:40
你这里不是没被final修饰吗?

java不是默认的吗?  不写也应该有吧?看老师的视频里面都没有写呢
作者: yemenglin    时间: 2014-5-9 22:07
伍叶竹 发表于 2014-5-8 22:13
你这里是str指向的内容不再是abcdefg字符串了,被重新赋值了。 而abcdefg字符串还是存在,还是不变的。认真 ...

也就是说String在堆内存中又new了一个新的对象?
作者: yemenglin    时间: 2014-5-9 22:08
jsjchenlong 发表于 2014-5-8 23:03
请看我下面的代码,希望对你的理解有帮助

        public static void main(String[] args) {

解释的非常详细  感谢
作者: 轻语。    时间: 2014-5-9 22:16
yemenglin 发表于 2014-5-9 22:07
也就是说String在堆内存中又new了一个新的对象?

substring是取了字串。 而且返回值是一个新的字符串。 新的串仍然是由str指向。
原串没变。
结合String str = new String("abc");  创建了几个对象。
结合这个问题,你肯定会理解更深些。

作者: yemenglin    时间: 2014-5-9 22:25
伍叶竹 发表于 2014-5-9 22:16
substring是取了字串。 而且返回值是一个新的字符串。 新的串仍然是由str指向。
原串没变。
结合String s ...

String str = new String("abc");
这是创建了两个对象   一个new String()   一个"abc"   那这两个对象的内容都是abc吗?
作者: 时光♪微凉    时间: 2014-5-9 23:50
yemenglin 发表于 2014-5-9 22:05
java不是默认的吗?  不写也应该有吧?看老师的视频里面都没有写呢

你不会是高混淆了吧,如果不加final修饰只有在接口里面定义成员属性时才默认为常量,并且是默认的静态常量,其他的要写成常量那就要加final,另外final还可以修饰方法、类,称为最终方法、最终类,修饰方法就不可再重写,修饰类就不能被继承




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