15. 【Java教程】字符串

简介: 15. 【Java教程】字符串

在 Java 基本数据类型一节中,我们已经知道 Java 中有两大数据类型:一个是基本数据类型,另一个是引用数据类型。


字符串(String)便属于引用数据类型。字符串在 Java 程序中无处不在,其实我们在第一个 Java 程序中就已经使用过了字符串,打印语句中双引号中的Hello World就是一个字符串:System.out.println("Hello World");


本小节我们将介绍字符串的基础知识,告诉你如何创建一个字符串,也会讲到 Java 13支持的多行字符串的创建方法和注意事项,还会介绍很常用的字符串的连接操作,最后我们也会着重讨论字符串的一个重要特性:不可变性。


需要注意的是,String是在java.lang包中定义的内置类,了解它的相关操作需要面向对象的前置知识,为了减少初学者的困扰,字符串的相关操作不会在本小节讨论。我们将在完成面向对象的学习后专门讲解String类。

1. 什么是字符串

字符串(string)是由零个或多个字符组成的有限序列,它是编程语言中表示文本的数据类型。简单来说,字符串就是一串字符。

2. 创建字符串

2.1 创建字符和字符串

提到字符串,就很容易与字符关联起来,回忆我们已经学过的字符类型char,在代码中我们是这样创建字符的:

// 依次创建三个字符 你 真 棒
char c1 = '你';
char c2 = '真';
char c3 = '棒';

char类型不同的是,String类型使用双引号来表示一个字符串(例如:"字符串文字"),在代码中我们可以这样创建字符串:

String str = "你真棒";

我们再来看一个创建并打印字符串的程序示例:

public class StringTest1 {
    public static void main(String[] args) {
        // 创建一个空字符串
        String str1 = "";
        // 创建一个只包含一个字符的字符串
        String str2 = "q";
        // 创建包含多个字符的字符串
        String str3 = "mybj is great!";
        // 依次打印它们
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
    }
}

运行结果:

1. 
2. q
3. mybj is great!

字符串可以声明为空,因此第一行将打印一个空行。

2.2 创建多行字符串

Java 13 以后,我们可以使用三引号来表示一个多行字符串,被官方称为“文本块”。文本块常用来表示多行的或大段的文字。例如:

1. pupublic class StringTest3 {
    public static void main(String[] args) {
        String str = """
            Java 很棒!
            码云笔记很棒!!
            能够在码云笔记学 Java 更棒!!!""";
        System.out.println(str);
    }
}

Tips:

这里需要注意的是,文本块中起始的三引号后面要另起一行,也就是说下面这种写法是错误的:

String str = """Java 很棒!
      码云笔记很棒!!
      能够在码云笔记学 Java 更棒!!!""";

如果我们直接使用javac命令编译代码,将会报错:

javac StringTest3.java
StringTest3.java:4: 错误: 文本块 是预览功能,默认情况下禁用。
        String str = """
                     ^
  (请使用 --enable-preview 以启用 文本块)
1 个错误

报错告诉我们:文本块是预览功能,默认是禁用的。我们可以给编译器加上一些参数来编译执行代码:

$ javac -source 14 --enable-preview StringTest3.java
$ java --enable-preview StringTest3
Java 很棒!
码云笔记很棒!!
能够在码云笔记学 Java 更棒!!!

2. 字符串的连接

我们可以使用加法运算符+将字符串和任意其他的数据类型进行连接操作。

可以将两个或多个字符串连接在一起,例如:

public class StringJoinTest1 {
    public static void main(String[] args) {
        // 定义两个字符串
        String str1 = "Hello";
        String str2 = "码云笔记";
        // 将字符串str1连接一个空格,再连接str2,最后再连接一个感叹号
        String str3 = str1 + " " + str2 + "!";
        System.out.println(str3);
    }
}

运行结果:

$ javac StringJoinTest1.java
$ java StringJoinTest1
Hello 码云笔记!

我们还可以将字符串与其他类型的值相连接,例如:

public class StringJoinTest2 {
    public static void main(String[] args) {
        // 定义整型变量 age
        int age = 12;
        // 定义浮点型变量 height
        float height = 132.5f;
        // 定义一个字符串变量 name
        String name = "小明";
        // 将上面三个变量连接,拼成一个更长的字符串
        String result = name + "今年" + age + "岁了," + "他的身高为" + height + "cm";
        System.out.println(result);
    }
}

运行结果:

小明今年10岁了,他的身高为132.5cm

我们知道加法运算符除了可以连接字符串,也可以进行数学的加法运算。那我们再来看一个实例:

public class StringJoinTest3 {
    public static void main(String[] args) {
        // 定义两个整型变量a、b
        int a = 100;
        int b = 200;
        // 打印一个空字符串+a+b的值
        System.out.println("" + a + b);
    }
}

试想屏幕上将会得到什么结果呢?编译执行代码:

$javac StringJoinTest3
java StringJoinTest
100200

这里结果没有打印300的原因很简单: 按照从左到右的执行顺序,(空字符串 + 数值100)的运算结果应该是字符串100,然后再运算(字符串100+数值200),其最终结果为字符串100200。由于运算中有字符串的存在,+运算符在这里用于字符串的连接而不是数值的计算。


试想,如果将表达式中的操作数倒过来(即b + a + ""),将得到什么结果呢?

3. 字符串的不可变性

字符串有一个重要特性:不可变性。也就是说,字符串一经创建便无法修改。我们来看一个示例:

public class StringTest4 {
    public static void main(String[] args) {
        // 创建一个字符串 str
        String str = "hello mybj!";
        // 对 str 重新赋值
        str = "Java is great!";
        System.out.println(str);
    }
}

运行结果:

Java is great!

童鞋们可能发现,咦?不是说字符串一旦创建就无法修改了吗,怎么str变量依然被修改成了新的值?

这里直接给出答案:上述例子中,变量str没有修改,而是变量str的“指向”被修改了。

我们通过图示来描述上述代码的执行流程,首先创建一个str,指向"hello mybj!":

当对str重新赋值后,在内存中先创建了字符串"Java is great",然后改变了变量str的指向,原来的"hello mybj!"并没有发生改变:

4. 小结

通过本小节的学习,我们了解了字符类型char基本数据类型,而字符串类型String是引用类型。在创建字符串时,我们可以使用双引号表示,从Java 13起,加入了多行字符串的表示方法。字符串的连接操作是使用加法运算符实现的。最后要特别注意字符串的不可变性,这在面试中经常会考到。

相关文章
|
6天前
|
存储 Java 编译器
Java基础教程(五千字带你快速入门!)(二)
Java基础教程(五千字带你快速入门!)(二)
|
3天前
|
XML 测试技术 数据格式
《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)
【7月更文挑战第3天】TestNG教程展示了如何自定义日志记录。首先创建一个名为`TestLog`的测试类,包含3个测试方法,其中一个故意失败以展示日志。使用`Assert.assertTrue`和`Reporter.log`来记录信息。接着创建`CustomReporter`类,继承`TestListenerAdapter`,覆盖`onTestFailure`, `onTestSkipped`, 和 `onTestSuccess`,在这些方法中自定义日志输出。
21 6
|
3天前
|
Java 测试技术 Apache
《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)
【7月更文挑战第4天】Apache Log4j 是一个广泛使用的 Java 日志框架,它允许开发者控制日志信息的输出目的地、格式和级别。Log4j 包含三个主要组件:Loggers(记录器)负责生成日志信息,Appenders(输出源)确定日志输出的位置(如控制台、文件、数据库等),而 Layouts(布局)则控制日志信息的格式。通过配置 Log4j,可以灵活地定制日志记录行为。
18 4
|
4天前
|
Java API 索引
Java中的字符串与字符操作详解
Java中的字符串与字符操作详解
|
1天前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十八)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-下篇(详解教程)
【7月更文挑战第6天】本文介绍了如何使用Log4j2将日志输出到文件中,重点在于配置文件的结构和作用。配置文件包含两个主要部分:`appenders`和`loggers`。`appenders`定义了日志输出的目标,如控制台(Console)或其他文件,如RollingFile,设置输出格式和策略。`loggers`定义了日志记录器,通过`name`属性关联到特定的类或包,并通过`appender-ref`引用`appenders`来指定输出位置。`additivity`属性控制是否继承父logger的配置。
|
2天前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十七)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-上篇(详解教程)
【7月更文挑战第5天】Apache Log4j 2是一个日志框架,它是Log4j的升级版,提供了显著的性能提升,借鉴并改进了Logback的功能,同时修复了Logback架构中的问题。Log4j2的特点包括API与实现的分离,支持SLF4J,自动重新加载配置,以及高级过滤选项。它还引入了基于lambda表达式的延迟评估,低延迟的异步记录器和无垃圾模式。配置文件通常使用XML,但也可以是JSON或YAML,其中定义了日志级别、输出目的地(Appender)和布局(Layout)。
|
2天前
|
Java API 索引
Java中的字符串与字符操作详解
Java中的字符串与字符操作详解
|
2天前
|
IDE Java 测试技术
使用Java实现单元测试:JUnit教程
使用Java实现单元测试:JUnit教程
|
3天前
|
JSON Java 数据格式
前后端数据交换,JSON基础语法和JSON数据和Java对象转换,最快的对象转换,JSON{““}字符串如何写User{id=1,username=‘zhangsan‘,password=‘123‘}
前后端数据交换,JSON基础语法和JSON数据和Java对象转换,最快的对象转换,JSON{““}字符串如何写User{id=1,username=‘zhangsan‘,password=‘123‘}
|
4天前
|
Java 测试技术 Android开发
《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程
【7月更文挑战第2天】TestNG是一个用于自动化测试的Java框架,提供日志记录功能。日志有两种模式:底层级详细记录每个步骤,高层级仅记录关键事件。示例代码展示了如何在测试方法中使用`Reporter.log()`记录信息,这些信息会显示在TestNG HTML报告中。文章还提及了日志显示时可能出现的编码问题及解决办法。