数组是不可变的

  1. Demo and Analysis
  2. 数组元素的可变性
    1. 1)数组元素是不可变的字符串
    2. 2)数组元素是可变的整型

Demo and Analysis

数组是不可变的,与字符串的不可变一样。下面看起来好像数组改变了,实际上数组是不可改变的,改变的是变量ns的 “指向” 。

public static void main(String[] args) {
    int[] ns;
    ns = new int[] { 68, 79, 91, 85, 62 };
    System.out.println(ns.length); // 5

    ns = new int[] { 1, 2, 3 };
    System.out.println(ns.length); // 3
}

执行 ns = new int[] { 68, 79, 91, 85, 62 } 时,JVM虚拟机先创建了一个数组,然后把数组变量ns指向它;

     ns

      │
      ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │68 │79 │91 │85 │62 │   │
└───┴───┴───┴───┴───┴───┴───┘

执行 ns = new int[] { 1, 2, 3 } 时,JVM虚拟机创建了一个新的数组,然后把数组变量ns指向它;

     ns ──────────────────────┐
                              │
                              ▼
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│   │68 │79 │91 │85 │62 │   │ 1 │ 2 │ 3 │   │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘

数组元素的可变性

数组元素的可变性与数组无关,取决于元素类型。

1)数组元素是不可变的字符串

比如下面程序中,数组元素是字符串类型,原字符串 “XYZ” 的内容是不可改变的,我们只能创建新的字符串并让数组元素指向新创建的字符串。

public static void main(String[] args) {
    String[] names = {"ABC", "XYZ", "zoo"};
    String s = names[1];
    names[1] = "cat";
    System.out.println(s);  //  输出XYZ
    System.out.println(names[1]);  //  输出cat
}

对于String[]类型的数组变量names,它实际上包含3个元素,但每个元素都指向某个字符串对象。

          ┌─────────────────────────┐
    names │   ┌─────────────────────┼───────────┐
      │   │   │                     │           │
      ▼   │   │                     ▼           ▼
┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┐
│   │░░░│░░░│░░░│   │ "ABC" │   │ "XYZ" │   │ "zoo" │   │
└───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┘
      │                 ▲
      └─────────────────┘

names[1] = "cat",就是创建了新的字符串 “cat” ,然后将数组names[1]指向它。也就是字符串””是不可变的

          ┌─────────────────────────────────────────────────┐
    names │   ┌─────────────────────────────────┐           │
      │   │   │                                 │           │
      ▼   │   │                                 ▼           ▼
┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┬───────┬───┐
│   │░░░│░░░│░░░│   │ "ABC" │   │ "XYZ" │   │ "zoo" │   │ "cat" │   │
└───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┴───────┴───┘
      │                 ▲
      └─────────────────┘

2)数组元素是可变的整型

如果数组元素是整型,由于整型是可变的,所以数组元素也是可变的。 ns[1] = 66 是使用新的值66覆盖 ns[1] 在内存中存储单元保存的旧值。

public static void main(String[] args) {
    int[] ns = {50, 70, 90};
    ns[1] = 66;
}

执行 int[] ns = {50, 70, 90} ,在内存单元中结果如下所示;

     ns

      │
      ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │50 │70 │90 │   │   │   │
└───┴───┴───┴───┴───┴───┴───┘

执行 ns[1] = 66 ,在内存单元中结果如下所示。
由于为数组分配的是连续的存储单元,所以根据数组的引用(图中的指针)和数组下标,我们可以知道 ns[1] 的内存地址并使用新的值覆盖该存储单元保存的旧值。

     ns

      │
      ▼
┌───┬───┬───┬───┬───┬───┬───┐
│   │50 │66 │90 │   │   │   │
└───┴───┴───┴───┴───┴───┴───┘

他の者にできたか?ここまでやれたか?この先できるか?いいや、仆にしかできない!

目录
×

喜欢就点赞,疼爱就打赏