【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);
}

相关文章
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
604 5
|
存储 SQL 缓存
Java字符串处理:String、StringBuilder与StringBuffer
本文深入解析Java中String、StringBuilder和StringBuffer的核心区别与使用场景。涵盖字符串不可变性、常量池、intern方法、可变字符串构建器的扩容机制及线程安全实现。通过性能测试对比三者差异,并提供最佳实践与高频面试问题解析,助你掌握Java字符串处理精髓。
|
自然语言处理 Java Apache
在Java中将String字符串转换为算术表达式并计算
具体的实现逻辑需要填写在 `Tokenizer`和 `ExpressionParser`类中,这里只提供了大概的框架。在实际实现时 `Tokenizer`应该提供分词逻辑,把输入的字符串转换成Token序列。而 `ExpressionParser`应当通过递归下降的方式依次解析
601 14
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
存储 Java 程序员
Java 基础知识点全面梳理包含核心要点及难点解析 Java 基础知识点
本文档系统梳理了Java基础知识点,涵盖核心特性、语法基础、面向对象编程、数组字符串、集合框架、异常处理及应用实例,帮助初学者全面掌握Java入门知识,提升编程实践能力。附示例代码下载链接。
599 0
|
存储 安全 Java
2025 年最新 40 个 Java 基础核心知识点全面梳理一文掌握 Java 基础关键概念
本文系统梳理了Java编程的40个核心知识点,涵盖基础语法、面向对象、集合框架、异常处理、多线程、IO流、反射机制等关键领域。重点包括:JVM运行原理、基本数据类型、封装/继承/多态三大特性、集合类对比(ArrayList vs LinkedList、HashMap vs TreeMap)、异常分类及处理方式、线程创建与同步机制、IO流体系结构以及反射的应用场景。这些基础知识是Java开发的根基,掌握后能为后续框架学习和项目开发奠定坚实基础。文中还提供了代码资源获取方式,方便读者进一步实践学习。
3354 2
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
502 11
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
402 0
课时14:Java数据类型划分(初见String类)
课时14介绍Java数据类型,重点初见String类。通过三个范例讲解:观察String型变量、&quot;+&quot;操作符的使用问题及转义字符的应用。String不是基本数据类型而是引用类型,但使用方式类似基本类型。课程涵盖字符串连接、数学运算与字符串混合使用时的注意事项以及常用转义字符的用法。
547 9