Java中String类的两种创建方式

来源:互联网 发布:数控铣床简单编程实例 编辑:程序博客网 时间:2024/04/29 16:14

Java中String类的一些发现和思考

遇到的问题

之前在网上浏览别人家的博客时,看到这样的小程序:

    public static void main(String[] args){        String s1 = new String("cjt");        String s2 = new String("cjt");        System.out.println(s1==s2);    }

当时看到作者的答案是false,大脑瞬间没反应过来,觉得应该是作者手误,写错了。
回头越想越不对劲,就自己在eclipse上测试了一下,发现打印出来的答案真的是false。

    public static void main(String[] args){        String s1 = new String("cjt");        String s2 = new String("cjt");        String s3 = "cjt";        String s4 = "cjt";        System.out.println(s1.hashCode());        System.out.println(s2.hashCode());        System.out.println(s3.hashCode());        System.out.println(s4.hashCode());        System.out.println(s1==s2);        System.out.println(s2==s3);        System.out.println(s3==s4);    }
//控制台输出的结果是:    98541    98541    98541    98541    false    false    true

顿时让我困惑不解(不是说String类是不可修改的吗?既然已经创建了一个”cjt”的字符串对象,并且把引用复制给了s1,那么常量池中已经存在了”cjt”这个字符串了,再执行String s2 = new String(“cjt”)语句时,应该直接把常量池中的”cjt”字符串的引用直接赋值给s2,这样,s1和s2的引用就是指向同一个”cjt”字符串对象,打印的结果就是true,再说,既然打印出来的结果是false,为什么hashCode的值是一样的呢?)。后来百度了一下,发现我之前的理解是错误的= =。


自我的理解

String类创建字符串有两种方式。
第一种是直接把字符串赋值给String变量,如下:

    String s = "cjt";

第一种方式,JVM直接在字符串常量池中查找有没有”cjt”的字符串,如果存在,则直接返回引用给变量s,如果不存在,就直接新建一个”cjt”字符串,然后把引用赋值给变量s。

第二种是通过创建String对象的方式,如下:

    String s = new String("cjt");

而第二种方式,JVM也会在字符串常量池中查找有没有”cjt”的字符串,如果存在,则直接引用这个字符串在堆上新建一个String对象,如果不存在,就在常量池中新建一个”cjt”字符串,然后引用这个字符串在堆上新建一个String对象。

所以,通过第一种方式创建的字符串,引用的都是字符串常量池中的字符串,如果字符串相同,则引用相同,而通过第二种方式创建的,每创建一个新的String对象,在堆上就有一个新的地址存放String对象,所以,每次new String(),得到的引用是不同的。

那么,引用不同,为什么hashCode的值是一样的呢?
根据String类中重写的hashCode源码:

        public int hashCode() {        int h = hash;        if (h == 0 && value.length > 0) {            char val[] = value;            for (int i = 0; i < value.length; i++) {                h = 31 * h + val[i];            }            hash = h;        }        return h;    }

从源码中可以看到,String类中的hashCode()的值跟字符串的内容相关,由于本例中字符串都是”cjt”,所以hashCode的值也一样。

总结

①String类是final类型的,不可改变的。
②String类创建字符串的方式有两种,它们有一定的区别。

1 0
原创粉丝点击