Java String

字符串表示一个字符序列。在Java中,字符串就像其他对象一样是对象。Java中String的一个有趣之处在于它是不可变的。不可变意味着字符串一旦创建就不能更改或修改。我们将在后面的文章中讨论不变性,不要让我们忘记它。

字符串字面量只是双引号内的字符序列。

String str = "codekru" ;

首先,我们希望你熟悉字符串和内存,因为它提供了在Java中如何存储和访问字符串的见解。它将进一步帮助您更好地理解字符串的各种概念。

关于字符串和内存的事实

任何编程语言的关键目标之一是有效地使用内存。随着应用程序的增长,字符串文字可能会占用程序的大量内存。因此,为了使Java更高效,JVM留出了一个称为String常量池的特殊内存区域。


当编译器遇到一个String文字时,它会检查String池,看看是否已经存在一个相同的String。如果该字符串已经存在,则对新文本的引用将定向到该现有字符串,因此不会创建新的String文本。

referencing the same literal


那些在堆和字符串常量池之间混淆的人,不要担心,记住,我们说过JVM会留出一个特殊的内存区域。这个特殊的区域在堆本身之内。下面的图表可以进一步说明这一点。

Heap and String pool

现在,你一定开始明白为什么不变性在字符串中至关重要了吧?


如果多个变量引用同一个String而不知道它,如果其中任何一个变量都可以改变String的值,那就太糟糕了。假设有两个变量s1和s2引用同一个String(“codekru”),那么如果s1以某种方式改变了String的值,它也会影响s2。

你现在可能会说,如果有人覆盖了String类的功能呢?不会在池里引起问题的东西吗?


这是String类被标记为final的主要原因之一。没有人可以覆盖String方法的功能。因此,我们可以放心,String对象将始终是不可变的。

How to create new Strings如何创建新字符串

创建字符串有很多方法,但我们将讨论最常用的方法。

 Using String literals使用字符串文字


我们必须将字符串写在双引号中,就是这样。让我们假设池中还不存在String对象。

String str = "codekru" ;   // creates one String object and one reference variable

它将在String池中创建“codekru”,str变量将引用它。


如果我们创建另一个变量s2,使用相同的字符串文字“codekru”呢?现在,它不会创建另一个字符串字面量。相反,它将引用已经存在的一个,这可以通过使用==运算符来证明。

public class Codekru {

    public static void main(String[] args) {
        String str = "codekru";
        String s2 = "codekru";
        if (str == s2) {
            System.out.println("referring to the same instance");    // will print this
        } else {
            System.out.println("Not referring to the same instance");
        }
    }
}

产出-

referring the same instance
Using String() constructor使用String()构造函数

We can also create a String object using the new keyword.
我们也可以使用new关键字创建一个String对象。

String str = new String("Codekru");      // creates two objects and one reference variable


由于我们使用了new关键字,Java将在普通(非池)内存中创建一个新的String对象,str将引用它。除此之外,文字“codekru”也将被放置在池中。

让我们尝试使用相同的字符串字面量(“codekru”)创建一个新对象

public class Codekru {

    public static void main(String[] args) {
        String str = new String("codekru");
        String s2 = new String("codekru");
        if (str == s2) {
            System.out.println("referring to the same instance");
        } else {
            System.out.println("Not referring to the same instance");
        }
    }
}

产出-

Not referring to the same instance

因此,我们可以看到每次使用new关键字后都会创建一个新的String对象。

现在,让我们回到String的不变性概念。看看下面的程序。

public class Codekru {

    public static void main(String[] args) {
        String str = "hello";
        str = str.concat(" codekru");
        System.out.println(str);
    }
}

产出-

hello codekru


现在,似乎弦已经改变了。之前是“你好”现在变成了“你好codekru”那么,关于String永远不能被更改或修改的说法是什么呢?
这里发生的是String本身没有改变。它只是创建了一个新的String,“hello codekru”,我们的变量现在只是指向它。所以,现在,我们在堆中有两个字面值。一个是“你好”,另一个是“你好codekru”。

variable referring to the new literal

Java字符串方法


Java为我们提供了许多方法来访问和执行对String的各种操作。其中一些列在下面-

  • charAt(int index):返回在指定索引处的字符值。
  • codePointAt(int index):返回指定索引处的字符(Unicode码点)。
  • compareTo(String anotherString):按字典顺序比较两个字符串。
  • concat(String str):将指定字符串连接到此字符串的结尾。
  • contains(CharSequence s):如果且仅如果此字符串包含指定的字符序列,则返回true
  • endsWith(String suffix):检查字符串是否以指定的后缀结束。
  • equalsIgnoreCase(String anotherString):在忽略大小写的情况下比较两个字符串。
  • length():返回字符串的长度。
  • indexOf(int ch):返回指定字符在此字符串中第一次出现的索引。
  • indexOf(String str):返回指定子字符串在此字符串中第一次出现的索引。
  • isEmpty():如果字符串的长度为0,则返回true
  • strip():返回移除了所有前导和尾随空白字符的字符串。
  • split(String regex):根据匹配给定的正则表达式的位置拆分此字符串。
  • startsWith(String prefix):检查字符串是否以指定的前缀开始。
  • substring(int beginIndex):返回从指定索引处开始的字符串的子字符串。
  • toCharArray():将字符串转换为新的字符数组。
  • toLowerCase():将此字符串中的所有字符转换为小写。
  • toUpperCase():将此字符串中的所有字符转换为大写。
  • valueOf()(注意:此处的描述可能不完整,因为valueOf有多个重载版本):返回参数的字符串表示形式。
  • trim():返回移除了所有前导和尾随空格的字符串。
  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知识的宝藏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值