如何创建可访问但不可变的静态数组字段?

时间:2018-03-01 21:52:29

标签: java

在“Effective Java”(第2版),第70页,它指出:

  

请注意,非零长度数组始终是可变的,因此它是错误的   使类具有公共静态最终数组字段或访问器   返回这样一个字段。如果一个类有这样的字段或访问者,   客户端将能够修改数组的内容。这是一个   频繁的安全漏洞来源:

     
// Potential security hole!
public static final Thing[] VALUES = { ... }
     

然后,本书提出以下解决方案:

private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
    return PRIVATE_VALUES.clone();
}

但是,我不知道这是如何解决这个问题的。

请考虑以下代码:

import java.util.*;

class Thing {
    public int yolo = 4;
}

class Test {
    private static final Thing[] VALUES = { new Thing(), new Thing() };
    public static final Thing[] values() {
        return VALUES.clone();
    }
}

public class MyClass {
    public static void main(String args[]) {
        Test.values()[0].yolo = 5;
        System.out.println(Test.values()[0].yolo);
    }
}

上面的代码打印“5”作为输出。我错过了什么,或者这本书是错误的吗?

1 个答案:

答案 0 :(得分:0)

您不是要更改原始数组VALUES

调用Test.values()时,它返回VALUES数组的 clone 而不是原始数组本身。您修改了克隆数组,因此输出为5;原始数组没有被修改。