Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在构造函数中复制对象(而不是对象引用)_Java_List_Unit Testing_Constructor_Pojo - Fatal编程技术网

Java 如何在构造函数中复制对象(而不是对象引用)

Java 如何在构造函数中复制对象(而不是对象引用),java,list,unit-testing,constructor,pojo,Java,List,Unit Testing,Constructor,Pojo,我有一个相当简单的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()

我有一个相当简单的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
{
私有最终int id;
私有最终列表名称;//名称是另一个POJO
POJO(最终整数id、最终列表名称)
{
this.id=id;
this.names=名称;
}
public int getId(){return id;}
public List 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; }
}
类名
{
私有最终字符串名;
私有最终字符串lastName;
POJO(最终字符串名、最终列表名)
{
this.firstName=firstName;
this.lastName=lastName;
}
public int getFirstName(){return firstName;}
public int getLastName(){return lastName;}
}
类POJO存储对名称列表的引用。为了安全起见,我想复制一份检索到的列表。为此,我尝试将构造函数修改为

this.names = new ArrayList<>();
this.names.addAll(names);
this.names=new ArrayList();
this.names.addAll(名称);
这是我的测试:

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());
    }
}

公共类POJOTest
{
私有最终int id=1;
私有最终列表名称=Mockito.mock(List.class);
私有最终POJO目标=新POJO(id、名称);
@试验
公共void testGetMethods()
{
Assert.assertEquals(id,target.getId());
Assert.assertEquals(name,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.lang.NullPointerException
在java.util.ArrayList.addAll(ArrayList.java:582)
在POJO(POJO.java:38)
POJOTest.(POJOTest.java:17)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)
位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
位于java.lang.reflect.Constructor.newInstance(Constructor.java:423)
位于org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:217)
位于org.junit.runners.BlockJUnit4ClassRunner$1.runReflectCall(BlockJUnit4ClassRunner.java:266)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:363)
位于org.junit.runner.JUnitCore.run(JUnitCore.java:137)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
位于com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
位于com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
位于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;
    }

public boolean addAll(Collection根据您的问题,不清楚要将名称列表的副本存储在何处。
我在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;
     }
}

封装测试;
导入java.util.ArrayList;
公共类POJOTest{
公共静态void main(字符串[]args){
姓名a=新姓名(“威尔”、“史密斯”);
姓名b=新姓名(“布鲁斯”、“韦恩”);
名称c=新名称(“威尔”、“特纳”);
ArrayList namelist=新的ArrayList();
名单。增加(a);
名单。增加(b);
名单。添加(c);
POJO p=新POJO(1,名称列表);
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));
}
}

您看过ArrayList.java:582了吗?您认为什么引用是空的?请在您的问题中包括您的测试用例和POJO构造函数的实际代码。我已经添加了更多的细节。现在您已经看过addAll的代码了,您知道NPE的直接原因是什么吗?也就是说,哪个取消引用导致了NPE?学习这一点很重要。我不确定。'names'是否为null?第582行是
int numNew=a.length
,因此我们怀疑c.toArray()的结果为null。你能明白为什么吗?c在这一点上有什么值?在模拟上调用方法时会发生什么?
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));
     }
}