我有一个类(class) SomeClass
那有一个List<String> someList
在里面。我需要让其他类遍历列表元素,但不让它们更改列表或列表元素。测试以下代码:
public class SomeClass {
static private List<String> someList;
public static List<String> getSomeList() {
return someList;
}
SomeClass(Array<String> someArray){
someList=Collections.unmodifiableList(Arrays.asList(someArray));
}
}
public class DoSomething {
for (String s : SomeClass.getSomeList()){
s+="Gotcha";
}
}
将显示 s 将仅在该 for 循环内更改 - 一旦完成,getSomeList() 将返回良好的旧列表,因此不会保存任何更改。同样尝试调用 getSomeList().add("someString") 将导致异常:UnsupportedOperationException。 请(向经验丰富的 C 编码人员)解释此行为背后的逻辑以及我如何捕获该异常?
最佳答案
String 的 +=
运算符实际上创建了一个 String 的新实例,而不是修改原始字符串对象。也就是说,下面两行代码是等价的:
s += "Gotcha"
s = new String(s + "Gotcha");
例子
下面是一个与您的 doSomeThing
public class st {
public static void main(String[] args) {
String hello = "hello";
String helloReference = hello; // making helloReference and hello refer to same object.
helloReference += " world"; // perform +=
System.out.format("`hello` = %s, `helloReference` = %s\n",
hello, helloReference);
}
}
其输出如下,这表明 hello
引用的对象不受 helloReference
执行的 +=
运算符的影响:
hello = `hello`, helloReference = `hello world`
在另一个世界,在 += 运算符之前:
hello helloReference
| |
-------------------------------
| "hello" |
-------------------------------
在 += 运算符之后,它将创建一个新实例并修改 helloReference
引用的对象:
hello helloReference
| | --------------------
| --------------| "hello world" |
------------------------------- --------------------
| "hello" |
-------------------------------
因此您的代码可以安全运行,在您的 doSomeThing 中执行的操作将影响您的 SomeClass 引用的对象:
public class DoSomething {
for (String s : SomeClass.getSomeList()){
// this create an new string instance to s
s+="Gotcha";
}
}
关于java - 对私有(private)列表问题的迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17350820/