杰瑞科技汇

Java String是基本类型吗?

Java 中的 String 不是基本类型,而是引用类型。

Java String是基本类型吗?-图1
(图片来源网络,侵删)

这是一个必须牢记的重要知识点,Java 的设计者将数据类型分为两大类:基本类型和引用类型。


Java 的基本类型

Java 语言定义了 8 种基本数据类型,它们是 Java 语言最基础的组成单元,用于定义简单的变量,它们的特点是:

  • 值存储在栈内存中:变量的值直接存储在变量所在的内存空间里。
  • 效率高:因为数据结构简单,直接操作值,所以速度很快。
  • 没有方法:基本类型本身不具备任何行为(方法),它们只是纯粹的值。
  • 大小固定:每种基本类型都有固定的大小,不随平台变化。

这 8 种基本类型可以分为四类:

类型 大小 (字节) 默认值 包装类 描述
byte 1 0 Byte 8位有符号整数
short 2 0 Short 16位有符号整数
int 4 0 Integer 32位有符号整数
long 8 0L Long 64位有符号整数
float 4 0f Float 32位单精度浮点数
double 8 0d Double 64位双精度浮点数
char 2 '\u0000' Character 16位 Unicode 字符
boolean (理论1) false Boolean 表示真或假

关键点String 不在这个列表里。

Java String是基本类型吗?-图2
(图片来源网络,侵删)

String 是引用类型

既然 String 不是基本类型,那它就是引用类型,引用类型的特点是:

  • 存储的是对象的内存地址(引用):变量本身不直接存储对象的数据,而是存储了指向该对象在堆内存中实际位置的地址。
  • 数据存储在堆内存中:对象(如 String 对象)及其数据存储在堆内存中。
  • 可以调用方法:因为 String 是一个类,所以它的实例(对象)可以调用类中定义的方法,如 .length(), .substring(), .equals() 等。
  • 默认值为 null:引用类型变量的默认值是 null,表示它没有指向任何有效的对象。

String 的特殊之处

String 在 Java 中是一个非常特殊的引用类型,它有一些独特的性质,这些性质有时会让人误以为它是基本类型:

  1. 不可变性

    • String 对象一旦被创建,其内容(内部的字符数组)就不能被修改
    • 当你像这样操作时:String s = "hello"; s = "world";,你并没有修改原来的 "hello" 对象,而是创建了一个新的 "world" 对象,然后让引用变量 s 指向了这个新对象,原来的 "hello" 对象如果没有其他引用指向它,就会被垃圾回收器回收。
    • 这种设计带来了线程安全和性能优化(例如字符串常量池)。
  2. 字面量语法

    Java String是基本类型吗?-图3
    (图片来源网络,侵删)
    • 你可以使用双引号 来直接创建一个 String 对象,如 String str = "abc";,这种语法非常方便,看起来像是在使用基本类型。
    • 编译器会自动处理这个语法,它会在堆内存(或字符串常量池)中创建一个 String 对象。
  3. 字符串常量池

    • 为了提高性能和减少内存开销,Java 使用了一个特殊的内存区域——字符串常量池。
    • 当你使用字面量 String s = "abc"; 创建字符串时,JVM 首先会检查常量池中是否已经存在 "abc" 这个字符串,如果存在,就直接返回该对象的引用;如果不存在,就创建一个新的并放入池中。
    • 这与通过 new 关键字创建字符串不同:String s = new String("abc");强制在堆上创建一个新的对象,即使常量池中已经存在 "abc"

如何区分: 与 equals()

这是理解 String 作为引用类型最关键的实践点。

  • 操作符

    • 对于基本类型: 比较的是是否相等。
    • 对于引用类型: 比较的是两个引用变量是否指向同一个内存地址(即是否是同一个对象)。
  • equals() 方法

    • 对于引用类型,equals() 方法通常用于比较两个对象的内容(逻辑上)是否相等。
    • String 类重写了 Object 类的 equals() 方法,专门用于比较两个字符串的字符序列是否完全相同。

示例代码

public class StringComparison {
    public static void main(String[] args) {
        // 情况1:使用字面量创建,指向常量池中的同一个对象
        String s1 = "hello";
        String s2 = "hello";
        System.out.println("s1 == s2: " + (s1 == s2)); // true (地址相同)
        System.out.println("s1.equals(s2): " + s1.equals(s2)); // true (内容相同)
        System.out.println("--------------------");
        // 情况2:使用 new 关键字创建,在堆上创建新对象
        String s3 = new String("world");
        String s4 = new String("world");
        System.out.println("s3 == s4: " + (s3 == s4)); // false (地址不同,是两个不同的对象)
        System.out.println("s3.equals(s4): " + s3.equals(s4)); // true (内容相同)
        System.out.println("--------------------");
        // 情况3:混合比较
        String s5 = "java";
        String s6 = new String("java");
        System.out.println("s5 == s6: " + (s5 == s6)); // false (一个指向常量池,一个指向堆)
        System.out.println("s5.equals(s6): " + s5.equals(s6)); // true (内容相同)
        System.out.println("--------------------");
        // 情况4:基本类型比较
        int a = 10;
        int b = 10;
        System.out.println("a == b: " + (a == b)); // true (值相同)
    }
}
特性 基本类型 引用类型 (以 String 为例)
类别 byte, short, int, long, float, double, char, boolean 所有类、接口、数组,包括 String
存储位置 栈(存储引用/地址),堆(存储对象数据)
默认值 具体的零值 (如 0, false, '\u0000') null
行为 无方法,只有值 可以调用方法(如 str.length()
比较方式 比较值 比较地址是否相同;equals() 通常比较内容
String 特点 - 不可变性字面量语法字符串常量池

请务必记住:String 是一个对象,是 Java 中最重要的引用类型之一,而不是基本类型。

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