Java 数据类型

Java 是强类型语言,每个变量使用前必须指定类型。Java 的数据类型分两大阵营:基本类型(8 种,小写关键字)和引用类型(类、接口、数组、枚举)。理解它们的区别,是写 Java 代码的根本。

1. 八种基本类型(Primitive Types)

Java 一共 8 种基本类型,分为四类:整型、浮点、字符、布尔。它们直接存值,内存分配在栈上,效率高。

public class BasicTypes {
    public static void main(String[] args) {
        // 整数类型
        byte b = 100;              // 1 字节,-128 ~ 127
        short s = 1000;            // 2 字节
        int i = 100000;            // 4 字节(最常用)
        long big = 10000000000L;   // 8 字节,字面量后加 L

        // 浮点类型
        float f = 3.14f;           // 4 字节,字面量后加 F
        double d = 3.141592653;    // 8 字节(最常用)

        // 字符类型
        char c = 'A';              // 2 字节,单引号,存 Unicode

        // 布尔类型
        boolean ok = true;         // true 或 false

        System.out.println(b + " " + s + " " + i + " " + big);
        System.out.println(f + " " + d);
        System.out.println(c + " " + ok);
    }
}

记忆要点:

2. char 类型详解

char单字符类型,用单引号 ',占 2 字节,存的是 Unicode 编码——所以可以放中文、日文、emoji 等任何字符。

public class CharDemo {
    public static void main(String[] args) {
        char a = 'A';              // 字符
        char b = 65;               // 65 是 'A' 的 ASCII 码
        char c = '中';             // Java char 存 Unicode,可以放中文
        char d = '\u4e2d';          // 也可以用 Unicode 转义

        System.out.println(a);     // A
        System.out.println(b);     // A(65 自动解释为字符)
        System.out.println(c);     // 中
        System.out.println(d);     // 中

        // char 本质是整数,可以做加减
        System.out.println(a + 1); // 66(char 提升为 int 参与运算)
    }
}

char 本质是无符号 16 位整数(0~65535),可以直接参与整数运算。但要注意 'a' + 1 的结果是 int 类型(98),不是字符 'b',要再强转回 char:(char)('a' + 1)。

3. 引用类型(Reference Types)

除了 8 种基本类型,其他都是引用类型——包括(如 String)、接口数组枚举。引用类型的变量存的是对象的地址(类似 C 的指针,但不能直接操作地址)。

public class RefTypeDemo {
    public static void main(String[] args) {
        // 基本类型:直接存值
        int a = 10;
        int b = a;             // b 复制 a 的值
        b = 20;
        System.out.println(a); // 10(a 不受 b 影响)

        // 引用类型:存的是对象的地址
        int[] arr1 = {1, 2, 3};
        int[] arr2 = arr1;     // arr2 复制 arr1 的地址,两者指向同一个数组
        arr2[0] = 99;
        System.out.println(arr1[0]);   // 99(arr1 也变了!)

        // 字符串是引用类型,但表现像基本类型(不可变)
        String s1 = "hello";
        String s2 = s1;
        s2 = "world";
        System.out.println(s1);    // hello(String 不可变,s1 不受影响)
    }
}

关键区别:基本类型赋值是复制值,引用类型赋值是复制地址(两个变量指向同一对象)。这就是为什么修改 arr2 会影响 arr1——它们其实指向同一个数组

String 比较特殊:它是引用类型,但不可变(immutable),所以表现有点像基本类型——重新赋值不会改原对象,而是指向新对象。

4. 包装类(Wrapper Classes)

有时候你需要把基本类型当作对象来用——比如放进集合(List<int> 是不允许的!)。Java 为每种基本类型提供了一个包装类(首字母大写),位于 java.lang 包:

import java.util.List;
import java.util.ArrayList;

public class WrapperDemo {
    public static void main(String[] args) {
        // 基本类型 -> 对应的包装类
        // byte    -> Byte
        // short   -> Short
        // int     -> Integer
        // long    -> Long
        // float   -> Float
        // double  -> Double
        // char    -> Character
        // boolean -> Boolean

        // 自动装箱(autoboxing):int -> Integer
        Integer i1 = 100;          // 等价于 Integer.valueOf(100)
        // 自动拆箱(unboxing):Integer -> int
        int i2 = i1;               // 等价于 i1.intValue()

        // 为什么要包装类?
        // 集合只能装对象,不能装基本类型
        List<Integer> nums = new ArrayList<>();
        nums.add(1);              // int 自动装箱成 Integer
        nums.add(2);
        int sum = nums.get(0) + nums.get(1);   // Integer 自动拆箱
        System.out.println(sum);   // 3
    }
}

自动装箱/拆箱是 Java 5 引入的语法糖,编译器自动插入 valueOf()xxxValue() 调用。但有几个坑:

5. 类型转换

不同类型之间可以互转,规则:

public class TypeConvert {
    public static void main(String[] args) {
        // 1. 自动(隐式)类型转换:小类型 -> 大类型,不丢精度
        int i = 100;
        long l = i;            // int(4字节) -> long(8字节),自动
        double d = l;          // long -> double,自动
        System.out.println(l + " " + d);   // 100 100.0

        // 2. 强制(显式)类型转换:大类型 -> 小类型,可能丢精度
        double pi = 3.99;
        int truncated = (int) pi;     // 强转成 int,直接截断小数部分
        System.out.println(truncated); // 3

        long big = 10000000000L;
        int small = (int) big;        // ⚠️ 超过 int 范围会溢出,结果不对!
        System.out.println(small);    // 1410065408(溢出后的怪值)

        // 3. 字符串与其他类型互转
        String s = "123";
        int n = Integer.parseInt(s);  // 字符串转 int
        String str = String.valueOf(n);    // int 转字符串
        String str2 = n + "";          // 最简单的转字符串技巧
        System.out.println(n * 2);    // 246
    }
}

新手要警惕溢出:强转超过目标类型范围时,Java 不会报错,而是会得到一个"怪值"(截断高位字节)。涉及金额、计数的转换要格外小心。

6. 基本类型 vs 包装类,选哪个?

小结

这一章你掌握了 Java 的类型体系:8 种基本类型、引用类型、包装类、类型转换。牢记基本类型存值、引用类型存地址这个本质区别。下一篇我们看 Java 运算符——怎么对这些类型做加减乘除、比较、逻辑运算。

← 上一篇 Java 变量

下一篇 Java 运算符

✈️💬