杰瑞科技汇

Java中String是什么意思?

一句话概括

String 在 Java 中是一个表示文本数据类型,但它不是像 intdouble 那样的基本数据类型,而是一个

Java中String是什么意思?-图1
(图片来源网络,侵删)

详细解释

String 是什么?

String 是 Java 中用来表示一串字符("Hello, World!")的类,当你想在程序中处理任何文本信息时,比如用户名、密码、消息、文件路径等,你都会用到 String

示例:

String name = "张三"; // 创建一个 String 对象,存储名字 "张三"
String message = "你好,Java!"; // 创建一个 String 对象,存储消息
System.out.println(name);
System.out.println(message);

String 的核心特点(非常重要)

理解 String 的以下几个特点,是掌握它的关键:

a) 不可变性

这是 String 最重要的一个特性,一旦一个 String 对象被创建,它的内容就不能被修改

Java中String是什么意思?-图2
(图片来源网络,侵删)

如何理解“不可变”?

  • 不是不能重新赋值:你可以让一个 String 变量引用一个新的字符串,但这不代表原来的字符串被修改了。
  • 底层原理String 内部的字符数组被 final 修饰,并且没有提供任何可以修改这个数组内容的方法。

举个例子:

String str1 = "hello";
// 看似修改了 str1,但实际上发生了以下事情:
// 1. JVM 在内存中创建了一个新的字符串 "hello world"。
// 2. 变量 str1 不再指向原来的 "hello",而是指向了这个新的 "hello world"。
// 3. 原来的 "hello" 对象如果没有被其他变量引用,就可能被垃圾回收器回收。
str1 = str1 + " world"; 
System.out.println(str1); // 输出: hello world

为什么 String 要设计成不可变?

  1. 安全性:在多线程环境下,如果字符串可以被修改,一个线程修改了字符串的内容,可能会导致其他依赖该字符串的线程出现问题,不可变性保证了线程安全。
  2. 性能优化:因为 String 不可变,JVM 可以对它进行一些优化,对于 "a" + "b" 这样的操作,编译器会直接优化成 "ab",而不是创建两个临时对象,更重要的是,Java 使用了一个叫做 字符串常量池 的机制,当你创建一个字符串字面量(如 String s = "abc")时,JVM 会先在常量池中查找是否存在 "abc",如果存在就直接引用,不存在才创建新的,这大大节省了内存。

b) String 对象的创建方式

有两种主要的创建方式,它们的内存行为不同:

Java中String是什么意思?-图3
(图片来源网络,侵删)
  1. 字面量赋值(推荐)

    String str = "hello";

    这种方式创建的字符串,会首先被放入字符串常量池,如果池中已有相同内容的字符串,则直接引用,不会创建新对象。

  2. 使用 new 关键字

    String str = new String("hello");

    这种方式一定会在堆内存中创建一个新的 String 对象,即使常量池中已经存在 "hello",它会先检查常量池,如果有 "hello",就直接用,然后在堆里再创建一个一模一样的对象。

对比:

// 方式一
String s1 = "hello";
String s2 = "hello";
// s1 和 s2 指向常量池中的同一个 "hello" 对象
System.out.println(s1 == s2); // 输出 true (== 比较的是内存地址)
// 方式二
String s3 = new String("hello");
String s4 = new String("hello");
// s3 和 s4 都是在堆中创建的新对象,地址不同
System.out.println(s3 == s4); // 输出 false
// s1 和 s3 一个在常量池,一个在堆,地址也不同
System.out.println(s1 == s3); // 输出 false

注意: 比较的是两个对象的内存地址(是否是同一个对象),而 String 类重写了 equals() 方法,equals() 比较的是两个字符串的内容是否相同。

System.out.println(s3.equals(s4)); // 输出 true (比较内容)

c) 常用方法

String 类提供了非常丰富的方法来操作字符串:

  • 获取信息

    • length(): 获取字符串长度。
    • charAt(int index): 获取指定索引位置的字符。
    • indexOf(String str): 查找子字符串第一次出现的位置。
  • 转换

    • toUpperCase() / toLowerCase(): 转换为大写/小写。
    • trim(): 去除字符串两端的空格。
    • split(String regex): 根据正则表达式分割字符串。
    • substring(int beginIndex, int endIndex): 截取子字符串。
  • 判断

    • equals(Object anObject): 比较内容是否相等。
    • equalsIgnoreCase(String anotherString): 忽略大小写比较内容。
    • startsWith(String prefix) / endsWith(String suffix): 判断是否以指定字符串开头/
    • contains(CharSequence s): 判断是否包含指定子序列。
  • 连接

    • 运算符:最简单直观的连接方式,编译器会优化成 StringBuilderappend() 方法。
    • concat(String str): 连接两个字符串。

示例:

String text = "  Hello Java  ";
System.out.println("原始字符串: '" + text + "'");
System.out.println("长度: " + text.length()); // 输出: 13
System.out.println("去除空格后: '" + text.trim() + "'"); // 输出: 'Hello Java'
System.out.println("转换为大写: " + text.toUpperCase()); // 输出:   HELLO JAVA  
System.out.println("是否包含 'Java': " + text.contains("Java")); // 输出: true

特性 描述
本质 一个 final 类,用于表示文本。
核心特点 不可变性:创建后内容不能被修改,任何修改操作都会创建新的 String 对象。
创建方式 字面量 (String s = "abc"):存于字符串常量池,节省内存。
new 关键字 (String s = new String("abc")):存于堆内存,一定会创建新对象。
比较 比较内存地址(是否是同一个对象)。
equals() 比较字符串内容(是否相同)。
用途 处理所有文本相关的数据,如用户输入、文件路径、消息等。
性能 由于不可变性,适合在多线程环境下使用,并且字符串常量池带来了内存和性能上的优势。

String Java 用来处理文本的工具箱,它的“不可变”是其设计的基石,带来了安全、高效和易于管理的优点。

分享:
扫描分享到社交APP
上一篇
下一篇