Java 私有问题列表上的迭代
我有一个类Java 私有问题列表上的迭代,java,list,exception-handling,iteration,private,Java,List,Exception Handling,Iteration,Private,我有一个类SomeClass,里面有一个列表someList。我需要让其他类在列表元素上迭代,但不允许它们更改列表或列表元素。测试以下代码: public class SomeClass { static private List<String> someList; public static List<String> getSomeList() { return someList; } SomeClass(Array&l
SomeClass
,里面有一个列表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";
}
}
公共类SomeClass{
静态私有列表;
公共静态列表getSomeList(){
返回一些列表;
}
SomeClass(数组someArray){
someList=Collections.unmodifiableList(array.asList(someArray));
}
}
公共级剂量测量{
for(字符串s:SomeClass.getSomeList()){
s+=“明白了”;
}
}
将显示s仅在for循环中更改-一旦完成,getSomeList()将返回良好的旧列表,因此不会保存任何更改。同时尝试调用getSomeList().add(“someString”)将导致异常:UnsupportedOperationException。
请(向经验丰富的C代码编写人员)解释此行为背后的逻辑,以及如何捕获该异常?字符串是不可变的对象,因此不能这样更改它们 其次,您不能在类主体中执行代码
DoSomething
类应该有一个方法可以:
public class DoSomething {
public static void doSomething() {
//code
}
}
对于列表,使用返回外部不可修改的列表(即,您仍然可以在SomeClass
中修改列表)
公共列表getInternalList(){
返回集合。不可修改列表(someList);
}
对于String,返回是安全的,因为String是一个。String的
+=
操作符实际上创建了一个新的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
引用的对象不受由hellorereference
执行的+=
运算符的影响:
hello = `hello`, helloReference = `hello world`
在另一个世界中,在+=运算符之前:
hello helloReference
| |
-------------------------------
| "hello" |
-------------------------------
在+=运算符之后,它将创建一个新实例,并修改hellorereference
引用到的对象:
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";
}
}
一旦完成,getSomeList()将返回良好的旧列表,因此
将保存更改
因为,就是这样,更改没有反映在最终列表中。。使用或代替String
作为列表的元素
同时尝试调用getSomeList().add(“someString”)将导致
异常:不支持操作异常
因为,返回的是数组中定义的嵌套类,如下所示:
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
这就是为什么您在从javadoc调用add(“某物”)
时得到,
List stooges=Arrays.asList(“Larry”、“Moe”、“Curly”),它将返回一个由指定数组支持的固定大小的列表。
因此,对该列表的任何修改都将导致java.lang.UnsupportedOperationException,即使代码中没有以下内容
Collections.unmodifiableList(Arrays.asList(someArray)) 您没有显示足够的SomeClass
。当我试图调用add()
@jlordo时,我看不出有什么原因导致不支持操作异常
:我已经添加了缺少的代码行(我想)这甚至不会编译…你说的是java传递的是引用而不是指针。在Java中有没有传递指针的方法(我说的是C程序员…)。对于文本图形,+1。只有=
可以传递Java中的引用,区别在于字符串的不可变性,它将在必要时创建一个新实例。对于那些设计为不可变的类,在创建后您无法更改它。
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
public boolean add(E e) {
throw new UnsupportedOperationException();
}