JAVA中String类分析

本文详细介绍了Java中String的创建方式,包括常量池的概念,并通过实例解析了不同创建方式下对象的创建数量。此外,还列举了String类的常用方法,如equals、charAt等,并探讨了StringBuilder和StringBuffer的区别,强调了线程安全和性能差异。最后,通过示例展示了StringBuilder和StringBuffer的操作方法。

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

一、String的创建

String  s1 = "hello world!";//第一种方式
String  s2 = new String("hello world!");//第二种方式

java中String类型的创建有以上两种方式 .

第一种方式 :
           创建的时候 , JVM会先在字符串常量池中去查找是否存在该字符串 , 如果存在直 接返回该字符 串对象的地址 , 否则会在常量池中创建该字符串对象并返回地址.

第二种方式 :
           创建的时候 , 也会先查找常量池中是否存在该字 符串 , 如果存在就会在堆里面复制一份这个字符串对象,然后把堆里面的对象地址返回给变量.不存在的话就会在堆中和常量池中各创建一个对象 , 并返回堆中对象的地址 . (关于常量池的内容,请参考常量池);

例1:
    String s1 = "zwz";
    问该句代码创建了几个对象?

    答案是1个,只在常量池中创建了一个对象.
例2:
    String s1 =new String( "zwz");
    问该句代码创建了几个对象?
    答案是2个,在常量池和堆中各创建了一个对象.
例3:
    String s1 = "zwz";
    String s1 =new String( "zwz");
    问这两句代码共创建了几个对象?
    答案是2个,在常量池和堆中各创建了一个对象.
例4:
    String s1 =new String( "cm");
    String s1 =new String( "cm");
    问这两句代码共创建了几个对象?
    答案是3个,第一句在常量池和堆内存中各创建了一个对象,第二句由于常量池中存在字符串对象,所以仅在堆内存中创建了一个对象.
例5:
    String s1 = "zwz"+"cm";
    问这句代码共创建了几个对象?
    答案是1个,“zwz”+"cm"在编译期就将字符串进行了连接,然后去常量池中查找有没有相同的字符串.

二、String常用的方法

①equals方法
     用来比较两个字符串内容是否相同.
②charAt方法
     返回指定索引处的字符
③contains方法
     判断字符串中是否包含另一个字符串
④ indexOf方法
     返回第一次出现某个字符串的位置
⑤isEmpty方法
     判断字符串是否是空字符串
⑥split方法
     将字符串分割,返回一个字符串数组
⑦trim方法
     返回去掉字符串开头和结尾的空格后的字符串
⑧toCharArray方法
     将字符串转换为字符数组
⑨replace方法
     替换原字符串中的某个字符或子字符串,全部替换
⑩length方法
     返回字符串的长度.

例子:

    String string =" hello world!!";
	System.out.println(string.charAt(1));
	System.out.println(string.contains("he"));
	System.out.println(string.indexOf("e"));
	System.out.println(string.isEmpty());
	System.out.println(string.split(" ")[0]);
	System.out.println(string.trim());
	System.out.println(string.toCharArray()[1]);//返回字符数组
	System.out.println(string.replace("!", "?"));
	System.out.println(string.length());
	System.out.println(string.lastIndexOf("!"));
h
true
2
false

hello world!!
h
 hello world??
14
13

重点介绍String的equals方法:

String类重写了equals方法,用来比较两个字符串的内容是否相同(和==做区分,==比较的是两个字符串对象的地址).

String类中equals具体是怎么实现的呢?

例:
s1.equals(s2)

实现:

首先调用==判断两个对象的地址是否相同,如果相同即是同一个对象,内容必定相同则返回true,
如果地址不相同则先判断传入的对象是否是String类的实例,如果不是直接返回false,
如果是String类的实例 则判断两个字符串的长度是否相等,不相等返回false,
如果长度相等的话就挨个比较两个字符串的字符数组,如果有一个不相同的话就返回false,都相同的话返回true.

看一下源码:

public boolean equals(Object anObject) {//anObject即为传入的String对象
        if (this == anObject) {//首先调用==判断两个对象的地址是否相同,如果相同即是同一个对象,返回true
            return true;
        }
        if (anObject instanceof String) {//如果地址不相同先判断传入的对象是否是String类的实例,如果不是直接返回false
            String anotherString = (String)anObject;
            int n = value.length;//value是字符串的字符数组
            if (n == anotherString.value.length) {//判断两个字符串的长度是否相等,不相等返回false
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {//长度相等的话就挨个比较两个字符串的字符数组,如果有一个不相同的话就返回false,都相同的话返回true
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

三、StringBuilder、StringBuffer区别

         StringBuffer和StringBuilder都继承自AbstraStringBuilder类,它们的使用方法都差不多.
        只不过StringBuffer类大部分方法都加上了synchronized关键字 , 这说明StringBuffer类是线程安全的 . 而StringBuilder类方法上都没有加该关键字,所以当有多个线程同时操作StringBuilder对象时, 可能就会发生线程安全问题.即StringBuilder类是线程不安全的(synchronized详解)
因此:
      需要线程安全就用StringBuffer,不需要就使用StringBuilder。
另外:
        String的每次改变都会涉及到字符数组的复制,而StringBuffer和StringBuilder直接在字符数组上改变;同时,StringBuffer是线程安全的,而StringBuilder线程不安全,没有StringBuffer的同步,所以StringBuilder快于StringBuffer。

StringBuilder部分源码:

    @Override
    public StringBuilder append(char c) {
        super.append(c);
        return this;
    }

StringBuffer部分源码:

    @Override
    public synchronized StringBuffer append(char c) {
        toStringCache = null;
        super.append(c);
        return this;
    }

同一种方法StringBuilder没有加上synchronized关键字,StringBuffer加上了synchronized关键字.

使用:

StringBuilder builder = new StringBuilder("hello world!!");
		StringBuffer buffer = new StringBuffer("hello world!!");
		StringBuilder append2 = builder.append("builder").delete(13, 20).insert(0, "builder:").reverse();
		StringBuffer append = buffer.append("buffer").delete(13,19).insert(0, "buffer:").reverse();
		System.out.println(append2);
		System.out.println(append);

输出:

Builder:!!dlrow olleh:redliub
Buffer:!!dlrow olleh:reffub
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值