Java中String类的两种创建方式

本文深入探讨了Java中String类的两种创建方式及其区别,通过实例分析了字符串常量池的作用及字符串比较运算符==和hashCode方法的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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类创建字符串的方式有两种,它们有一定的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值