Java常用类String类

Sting类结构刨析

        String对象用于保存字符串对象,其实也就是一组字符序列,字符串常量就是用双引号括起来的字符序列,字符是单引号例如 "hello".

了解一个首先了解它的继承图

部分源代码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

    /**
     * The value is used for character storage.
     *
     * @implNote This field is trusted by the VM, and is a subject to
     * constant folding if String instance is constant. Overwriting this
     * field after construction will cause problems.
     *
     * Additionally, it is marked with {@link Stable} to trust the contents
     * of the array. No other facility in JDK provides this functionality (yet).
     * {@link Stable} is safe here, because value is never null.
     */
    @Stable
    private final byte[] value;

这个继承图中有两个非常重要的接口,一个是 java.io.Serializable还有一个就Comparable<String>

那么分别介绍一些这两个接口

Serializable这个接口,就可以串行化,可以在网络传输,从他来自于io这个包就很明显可以看出和传输有关,在web开发中实体对象经常要实现这个接口。

comparable接口可以比较大小,可以只指定比规则,也可以,默认

这个就是那个比较方法 ,下面这段代码就是String实现这个接口的方法的具体实现

public int compareTo(String anotherString) {
        byte v1[] = value;
        byte v2[] = anotherString.value;
        if (coder() == anotherString.coder()) {
            return isLatin1() ? StringLatin1.compareTo(v1, v2)
                              : StringUTF16.compareTo(v1, v2);
        }
        return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
                          : StringUTF16.compareToLatin1(v1, v2);
     }

我们在开头介绍字符串就是一组字符序列,并且他就存放在value中

 @Stable
    private final byte[] value;

字符串的final不可修改是指装有字符的value的这个地址指向不能被修改,不是说值不能修改,

 也就是value这个变量他里面的值可以改变,但是他的地址指向不能改变,它的地址指向了方法区里面的常量池,发送变化的常量池里面的值,而不是放在堆里面的value地址

final 修饰引用数据类型的问题 - Java - Light_cone - 博客园

 String是一个final类不能被继承。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence 

Sting有很多的构造器,这只是一部分,常用的也就几个。

 以上内容主要讲的Sting的继承关系,和它的一个属性value.

String的创建刨析

案例

public class String01 {
    public static void main(String[] args) {
        String s1= "java";
        String s2= "java";
        String s3= new String("java");
    }
}

两种创建方式的区别

方式一:

String s1= "java";

第一种方式,是先检查常量池中是否有java的数据空间,如果有就直接指向,如果没有就创建。案例中执行s1这句时常量池中没有java,那么就创建。s2的值也是java,检查常量池中有,那么自己不创建,直接指向。

 

 方式二:

String s3= new String("java");

第二种方式会在堆中先创建空间,因为s3是一个对象,所有对象都在堆中,对象中有个value属性,这个呢就指向常量池,如果常量池中有呢就直接指向,没有就直接创建。这里就类似加了一个过度,栈中指向的是堆了。

 

 题目测试

System.out.println(s1.equals(s2));//T 这个比较的是值,当然为true
System.out.println(s1==s2);//T 这个比较的是地址当然也是,刚刚分析的时候,直接赋值的,就是有的话直接指向。

String的特性

        String是一个final类,代表不可变字符序列,字符串不可变。一个字符串一旦被分配不可变。这里站在的角度是在类上,而不是之前提到的value属性。String s2= "java";直接赋值这种其实也就和new类似,赋值一次也就相当于new,创建一次对象,所以s2=hello就是重新创建了一个对象,让后s2指向。总共创建了两个对象。

//创建了几个对象?
public class String01 {
    public static void main(String[] args) {
        String s2= "java";
        s2="hello";

String中的 "+" 的不同使用

public class String02 {
    public static void main(String[] args) {
        String a1="hell0";
        String a2="abc";

        String a3="hell0"+"abc";

        String a4=a1+a2;

        String a5="hell0abc";
    }
}

String a3="hell0"+"abc";和String a5="hell0abc";其实是一样的,java编译时会将String a3="hell0"+"abc"优化为String a5="hell0abc"这样。

String a4=a1+a2;就有所不同,
会先创建一个StringBuilder sb = StringBuilder()这么一个对象,然后调用sb.append()方法把两个字符串添加,然后再String a4=sb.toString(),这样就在堆中开辟了一个空间,a4指向堆,堆里面的value属性就指向常量池。所以a4和a3,a5不一样,一个指向堆,两个直接指向常量池。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值