java中的String

1 篇文章 0 订阅
1 篇文章 0 订阅

java中的String

  在编程语言中,都会有一种类型去储存字符串。java中用String来存储字符串,并且String在java中使用非常频繁,并且十分广泛。

String为什么不可变

  都说java是不可变的,不可变的原因是什么呢?
  String是final类,这和String的不可变有关系吗?首先我们要知道,final修饰在类上,只是代表着这个类是不能被继承的,并不能说不能改变这个类的值。
  所以,我们需要看一下String中用什么来存储实际的值。 private final char value[],这是jdk1.7中所用到的,10是用的byte数组。具体是在哪个版本改了,我就没去试了。那String的不可变是否和这个有关呢,答案是有关系,但并不是说就仅仅由它决定。
  final如果用在属性上会有什么效果呢?如果是基本数据类型,就不能改变其值。如果是引用数据类型,就不能指向新的对象,但是能改变其值。
  final char value[],数组不是引用数据类型吗,那我们就可以改变其中的值了吗?是不是有这个疑惑?这时候private就起作用了,外面就不能直接调用这个属性去进行改变了。外患解决了就只剩内忧了,我们来看看String中的方法

public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

  这是String中的字符串截取方法,仔细看他的返回,如果截取产生的字符串不等于本身就再new一个新的字符串,并不是将自身的值变成符合要求的字符串。String中的方法都是这个道理。
  所以说String不可变并不完全是final char value[]决定,更大的原因是String的设计,使String是一个不变的。

String中的intern

  String中的intern是一个本地方法,不是用java写的。这个方法是将字符串放入字符串常量池中的方法,不同版本效果不一样。下面看一段代码,jdk是使用1.6

public static void main(String[] args) {
        String s = new String("1");
        s.intern();
        String s2 = "1";
        System.out.println(s == s2);

        String s3 = new String("1") + new String("1");
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);
    }

看一下输出什么
在这里插入图片描述
  String s = new String(“1”)首先在常量池中创建“1”,s指向堆中的一个“1” ,s.intern() 因为常量池中有 “1”了,所以s.intern()只是返回池中“1”引用 所以s2和s指向不同,所以是false。如果你用一个变量var去接受s.intern(),那这个变量var是和s2相等的。
  String s3 = new String(“1”) + new String(“1”);在常量池创建了“1 “在堆中创建了两个匿名对象 堆中还有一个s3 此时字符串池中没有“11”, s3.intern()会在池中创建“11”并返回池中值的引用 此时s4和s3指向还是不一样,所以也为false。
  我们再看一下,同样的代码在1.7中输出什么。
在这里插入图片描述
  第一个false是同理的。主要是第二个为什么是true。
  因为在1.7时 s3.intern()会在常量池中放入s3这个引用,并返回s3这个引用, String s4 = "11"时,池中有值为"11"的引用, s4指向s3这个引用 所以相等。
  注意s3拼接成的字符串如果是java、main这些(String s3 = new String(“ja”) + new String(“va”)),因为它们会因为其他的类(不局限于自己写的)已经存在字符串常量池。所以s3.intern()!=s3,因为s3.intern()返回的是常量池的引用。如果是String s3 = new String(“he”) + new String(“llo”)这种,s3.intern()==s3,因为s3.intern()返回的就是自己放进去的s3

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值