【JavaSE】Java基础语法(三十七):Java 中的 String 类(源码级别)(1)

简介: String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。1. 构造方法1.1 String()

String 表示 字符串类型,属于 引用数据类型 。Java 中 String 是 不可变 的。

在 Java 当中 双引号 括起来的字符串,是直接存储在“方法区”的“字符串常量池”当中的。


1. 构造方法

1.1 String()

源码:

/** 
    初始化新创建的字符串对象,使其表示空字符序列。
 请注意,由于字符串是不可变的,因此不需要使用此构造函数。
*/
public String() {
    this.value = "".value;
}

1.2 String(String original)

源码:

/**
    初始化新创建的字符串对象,使其表示与参数相同的字符序列;
    换句话说,新创建的字符串是参数字符串的副本。
    除非需要original的显式副本,否则不需要使用此构造函数,因为字符串是不可变的。
*/
public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

1.3 String(char[] chars)

源码:

/**
分配一个新字符串,使其表示字符数组参数中当前包含的字符序列。
复制字符数组的内容;对字符数组的后续修改不会影响新创建的字符串。
参数:
value–字符串的初始值
*/
public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

1.4 String(char数组,起始下标,长度)

源码:

/**
    分配一个新字符串,该字符串包含字符数组参数子数组中的字符。
    offset参数是子数组第一个字符的索引,count参数指定子数组的长度。
    复制子数组的内容;对字符数组的后续修改不会影响新创建的字符串。
    参数:
    value–作为字符源的数组
    偏移量–初始偏移量
    计数–长度
    抛出:
    IndexOutOfBoundsException–如果偏移量和计数参数索引字符超出值数组的边界
*/
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.5 String(byte数组)

源码:

/**
    通过使用平台的默认字符集对指定的字节数组进行解码来构造新字符串。
    新字符串的长度是字符集的函数,因此可能不等于字节数组的长度。
    当给定字节在默认字符集中无效时,此构造函数的行为未指定。
    当需要对解码过程进行更多控制时,应使用CharsetDecoder类。
参数:
字节–要解码为字符的字节
Since: JDK1.1
*/ 
public String(byte bytes[]) {
     this(bytes, 0, bytes.length);
 }

1.6 String(byte数组,起始下标,长度)

源码:

/**
    通过使用平台的默认字符集对指定的字节子数组进行解码,构造一个新字符串。
    新字符串的长度是字符集的函数,因此可能不等于子数组的长度。
    当给定字节在默认字符集中无效时,此构造函数的行为未指定。
    当需要对解码过程进行更多控制时,应使用CharsetDecoder类。
参数:
字节–要解码为字符的字节
偏移量–要解码的第一个字节的索引
长度–要解码的字节数
抛出:
IndexOutOfBoundsException–如果偏移量和长度参数索引字符超出字节数组的边界
Since: JDK1.1
*/ 
public String(byte bytes[], int offset, int length) {
    //  checkBounds(bytes, offset, length);
    if (length < 0)
        throw new StringIndexOutOfBoundsException(length);
    if (offset < 0)
        throw new StringIndexOutOfBoundsException(offset);
    if (offset > bytes.length - length)
        throw new StringIndexOutOfBoundsException(offset + length);
    this.value = StringCoding.decode(bytes, offset, length);
}

1.7 String(StringBuffer buffer)

源码:

/**
    分配一个新字符串,该字符串包含字符串缓冲区参数中当前包含的字符序列。
    复制字符串缓冲区的内容;
    字符串缓冲区的后续修改不会影响新创建的字符串。
*/
synchronized(buffer) {
    this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
}

1.8 String(StringBuilder builder)

源码:

/**
    分配一个新字符串,该字符串包含字符串生成器参数中当前包含的字符序列。
    复制字符串生成器的内容;
    字符串生成器的后续修改不会影响新创建的字符串。
    提供此构造函数是为了方便迁移到StringBuilder。
    通过toString方法从字符串生成器获取字符串可能运行得更快,通常是首选方法。
    Since:JDK1.5
*/  
public String(StringBuilder builder) {
    this.value = Arrays.copyOf(builder.getValue(), builder.length());
}

2. 普通方法

https://blog.csdn.net/qq_44715943/article/details/116308837

2.1 char charAt(int index)

源码:

/**
    返回指定索引处的字符值。索引的范围从0到length()-1。
    序列的第一个字符值在索引0处,下一个字符值在索引1处,依此类推,就像数组索引一样。
    如果索引指定的char值是代理项,则返回代理项值。
参数:index–字符值的索引。
返回:此字符串指定索引处的char值。第一个char值位于索引0处。
抛出:IndexOutOfBoundsException–如果索引参数为负或不小于此字符串的长度。
*/
public char charAt(int index) {
    if ((index < 0) || (index >= value.length)) {
        throw new StringIndexOutOfBoundsException(index);
    }
    return value[index];
}

2.2 int compareTo(String anotherString)

源码:

public int compareTo(String anotherString) {
    int len1 = value.length;
    int len2 = anotherString.value.length;
    int lim = Math.min(len1, len2);
    char v1[] = value;
    char v2[] = anotherString.value;
    int k = 0;
    while (k < lim) {
        char c1 = v1[k];
        char c2 = v2[k];
        if (c1 != c2) {
            return c1 - c2;
        }
        k++;
    }
    return len1 - len2;
}

2.3 int indexOf(String str, int fromIndex)

源码:

 /**
    返回指定子字符串第一次出现的字符串内的索引,从指定的索引开始。
    返回的索引是最小的值k,其中:
    k>=fromIndex&amp;&amp;this。startsWith(str,k)
    如果不存在这样的k值,则返回-1。
    参数:
    str–要搜索的子字符串。
    fromIndex–开始搜索的索引。
    返回:指定子字符串第一次出现的索引,从指定的索引开始,如果没有出现,则为-1。
*/
public int indexOf(String str, int fromIndex) {
    return indexOf(value, 0, value.length,
                   str.value, 0, str.value.length, fromIndex);
}

2.4 int indexOf(String str)

源码:

/**
    返回指定子字符串第一次出现时该字符串内的索引。
    返回的索引是最小的值k,其中:
    这startsWith(str,k)
    如果不存在这样的k值,则返回-1。
    参数:str–要搜索的子字符串。
    返回:指定子字符串第一次出现的索引,如果没有出现,则为-1。
*/
public int indexOf(String str) {
    return indexOf(str, 0);
}

2.5 boolean contains(CharSequence s)

源码:

/**
    当且仅当此字符串包含指定的字符值序列时,返回true。
    参数:s–要搜索的序列
    返回:如果此字符串包含s,则为true,否则为false
    Since:1.5
*/
public boolean contains(CharSequence s) {
    return indexOf(s.toString()) > -1;
}

2.6 boolean startsWith(String prefix, int toffset)

源码:

/**
    测试此字符串中从指定索引开始的子字符串是否以指定前缀开始。
参数:
    prefix–前缀。
    toffset–从何处开始查看此字符串。
返回:
如果参数所表示的字符序列是从索引toffset开始的该对象的子字符串的前缀,则为true;否则就错了。
如果toffset为负值或大于该字符串对象的长度,则结果为false;否则,结果与表达式的结果相同
这子串(toffset)。startsWith(前缀)
*/
public boolean startsWith(String prefix, int toffset) {
    char ta[] = value;
    int to = toffset;
    char pa[] = prefix.value;
    int po = 0;
    int pc = prefix.value.length;
    // Note: toffset might be near -1>>>1.
    if ((toffset < 0) || (toffset > value.length - pc)) {
        return false;
    }
    while (--pc >= 0) {
        if (ta[to++] != pa[po++]) {
            return false;
        }
    }
    return true;
}

2.7 boolean startsWith(String prefix)

源码:

public boolean startsWith(String prefix) {
    return startsWith(prefix, 0);
}

2.8 boolean endsWith(String suffix)

源码:

public boolean endsWith(String suffix) {
    return startsWith(suffix, value.length - suffix.value.length);
}

2.9 boolean equals(Object anObject)

源码:

/**
*/
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

2.10 boolean equalsIgnoreCase(String anotherString)

源码:

public boolean equalsIgnoreCase(String anotherString) {
    return (this == anotherString) ? true
        : (anotherString != null)
    && (anotherString.value.length == value.length)
        && regionMatches(true, 0, anotherString, 0, value.length);
}

相关文章
|
17天前
|
安全 Java 数据建模
Java记录类:简化数据载体的新选择
Java记录类:简化数据载体的新选择
169 101
|
17天前
|
安全 Java 开发者
Java记录类:简化数据载体的新方式
Java记录类:简化数据载体的新方式
195 100
|
2月前
|
缓存 安全 Java
Java反射机制:动态操作类与对象
Java反射机制是运行时动态操作类与对象的强大工具,支持获取类信息、动态创建实例、调用方法、访问字段等。它在框架开发、依赖注入、动态代理等方面有广泛应用,但也存在性能开销和安全风险。本文详解反射核心API、实战案例及性能优化策略,助你掌握Java动态编程精髓。
|
21天前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
140 7
|
11月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
442 58
|
12月前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
196 3
|
12月前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
172 2
|
12月前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
244 1
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的

热门文章

最新文章