String源码解读

String是常量,在定义之后不能被改变,字符串缓冲区支持可变的字符串。因为String对象是不可变的,所以可以共享。

定义

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

String 是final类型,表示该类不能继承,同时实现了三个接口java.io.Serializable, Comparable<String>, CharSequence

属性

 private final char value[];

final类型的字符数组,用来存储字符串的内容,因为被final修饰,所以String一旦初始化之后是不能被更改的。

  private int hash;

缓存的hashCode值,默认为0。

  private static final long serialVersionUID = -6849794470754667710L;
   
  private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];

String实现了Serializable接口,所以支持序列化和反序列化。

java 的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性。在进行反序列化时,JVM会把传过来的字节流中的serialVersionUID与本地响应实体的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就抛出版本不一致的异常(InvalidCastException)。

构造方法

  1. 使用字符数组

当使用字符串数组创建的时候,会用的Arrays.copyOf方法和Arrays.copyOfRange方法。将源字符数组数据一一复制到String中的字符数组中。

  //offset为起始位置,count为数量
  public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
  1. 字符串构造

使用字符串创建时,会将源String中的valuehash两个属性直接赋值给目标String。

 public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
  1. 字节数组构造
    char[]字符数组是以unicode码来存储的,Stringchar 为内存形式,byte是网络传输或存储的序列化形式。可以通过charset来解码指定的byte数组,将其解码成unicode的char[]数组,构造String。
String(byte bytes[]) 

String(byte bytes[], int offset, int length)

String(byte bytes[], Charset charset)

String(byte bytes[], String charsetName)

String(byte bytes[], int offset, int length, Charset charset)

String(byte bytes[], int offset, int length, String charsetName)
  1. 使用StringbuiderStringBuffer构造
    虽然存在当前的构造方式,但是和toString()方法相比,效率比较低。所以可以直接使用toString()代替。
    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }

    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }

其他方法

getBytes

String s = "你好,世界!"; 
byte[] bytes = s.getBytes();

这段代码在不同的平台上运行得到结果是不一样的。由于没有指定编码方式,所以在该方法对字符串进行编码的时候就会使用系统的默认编码方式,比如在中文操作系统中可能会使用GBK或者GB2312进行编码,在英文操作系统中有可能使用iso-8859-1进行编码。这样写出来的代码就和机器环境有很强的关联性了,所以,为了避免不必要的麻烦,我们要指定编码方式。如使用以下方式:

比较方法

boolean equals(Object anObject);
boolean contentEquals(StringBuffer sb);
boolean contentEquals(CharSequence cs);
boolean equalsIgnoreCase(String anotherString); //使用toUpperCase方法转换成大写,在进行比较
int compareTo(String anotherString);
int compareToIgnoreCase(String str);
boolean regionMatches(int toffset, String other, int ooffset,int len);  //局部匹配
boolean regionMatches(boolean ignoreCase, int toffset,String other, int ooffset, int len);   //局部匹配
String s = "你好,世界!"; 
byte[] bytes = s.getBytes("utf-8");

其他

ength(); //返回字符串长度

isEmpty(); //返回字符串是否为空

charAt(int index;) //返回字符串中第(index+1)个字符

char[] toCharArray(); //转化成字符数组

trim();// 去掉两端空格

toUpperCase();// 转化为大写

toLowerCase();// 转化为小写

String concat(String str); //拼接字符串

String replace(char oldChar, char newChar); //将字符串中的oldChar字符换成newChar字符

//以上两个方法都使用了String(char[] value, boolean share);

boolean matches(String regex); //判断字符串是否匹配给定的regex正则表达式

boolean contains(CharSequence s); //判断字符串是否包含字符序列s

String[] split(String regex, int limit;) //按照字符regex将字符串分成limit份。

String[] split(String regex);
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值