我有一个相当简单的POJO:
class POJO
{
private final int id;
private final List<Name> names; //Name is another POJO
POJO(final int id, final List<Name> names)
{
this.id = id;
this.names = names;
}
public int getId() { return id; }
public List<Name> getNames() { return names; }
}
POJO名称如下:
class Name
{
private final String firstName;
private final String lastName;
POJO(final String firstName, final List<Name> names)
{
this.firstName = firstName;
this.lastName = lastName;
}
public int getFirstName() { return firstName; }
public int getLastName() { return lastName; }
}
POJO类存储对Name列表的引用。为了安全起见,我想复制检索到的列表。为此,我尝试将构造函数修改为
this.names = new ArrayList<>();
this.names.addAll(names);
这是我的测试
public class POJOTest
{
private final int id = 1;
private final List<Name> names = Mockito.mock(List.class);
private final POJO target = new POJO(id, names);
@Test
public void testGetMethods()
{
Assert.assertEquals(id, target.getId());
Assert.assertEquals(names, target.getNames());
}
}
我的测试用例失败
java.lang.NullPointerException
at java.util.ArrayList.addAll(ArrayList.java:582)
at POJO.<init>(POJO.java:38)
at POJOTest.<init>(POJOTest.java:17)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
这是java:582:
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
我在这里做错了什么?还有其他方法可以在构造函数中进行复制吗?
答案 0 :(得分:0)
根据您的问题,不清楚您要在哪里存储名称列表的副本。 我在POJO类中创建了一个副本,以便POJO类的每个实例都将拥有自己的名称列表副本。
package test;
import java.util.ArrayList;
import java.util.Iterator;
public class POJO {
private final int id;
private final ArrayList<Name> names; //Name is another POJO
private ArrayList<Name> namescopy;
POJO(int id, ArrayList<Name> names)
{
this.id = id;
this.names = names;
namescopy = new ArrayList<Name>();
Iterator<Name> it = names.iterator();
while(it.hasNext()) {
try { namescopy.add( (Name) it.next().clone()); } catch (CloneNotSupportedException e) {e.printStackTrace();}
}
}
public int getId() { return id; }
public ArrayList<Name> getNames() { return names; }
public ArrayList<Name> getNamesCopy() {
return namescopy;
}
}
package test;
public class Name implements Cloneable {
private final String firstName ;
private final String lastName;
Name( String firstName, String lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public Object clone() throws
CloneNotSupportedException
{
return super.clone();
}
}
package test;
import java.util.ArrayList;
public class POJOTest {
public static void main(String[] args) {
Name a = new Name("Will", "Smith");
Name b = new Name("Bruce", "Wayne");
Name c = new Name("Will", "Turner");
ArrayList<Name> namelist = new ArrayList<Name>();
namelist.add(a);
namelist.add(b);
namelist.add(c);
POJO p = new POJO(1, namelist);
p.getNames().forEach(i -> System.out.println(i.getFirstName()+" "+i.getLastName() +" "+ i));
System.out.println();
p.getNamesCopy().forEach(i -> System.out.println(i.getFirstName()+" "+i.getLastName() +" "+ i));
}
}