不调用复制构造函数,但调用默认构造函数 java

Posted

技术标签:

【中文标题】不调用复制构造函数,但调用默认构造函数 java【英文标题】:Copy Constructor is not called but default constructor is called java 【发布时间】:2017-07-28 09:06:09 【问题描述】:
package primary;

public class Room implements Cloneable

    int room_no;
    private int leftStrength; //number of students sitting on left side
    private int rightStrength;//number of students sitting on right side
    private int capacity;
    private int timeSlot;
    private boolean checkBig;
     boolean invigilanceRequired;
    private int rightCapacity;
    private int leftCapacity;
    public Room(int room_no,int capacity)
    
        this.room_no=room_no;
        this.capacity=capacity;
        rightStrength=0;
        leftStrength=0;
        timeSlot=0;
        checkBig=true;
        invigilanceRequired=true;
        rightCapacity=capacity;
        leftCapacity=capacity;
    

    public Room(Room other)
    
        this.room_no=other.room_no;
        this.capacity=other.capacity;
        this.rightStrength=other.rightStrength;
        this.leftStrength=other.leftStrength;
        this.timeSlot=other.timeSlot;
        this.checkBig=other.checkBig;
        this.invigilanceRequired=other.invigilanceRequired;
        this.rightCapacity=other.rightCapacity;
        this.leftCapacity=other.leftCapacity;
    
    @Override
    protected Object clone() throws CloneNotSupportedException 
        // TODO Auto-generated method stub
        return super.clone();
    


我已经尝试过复制构造函数和 clone() 来制作 Room 对象的副本,但每次它给出相同的对象并且不复制。我发现它总是调用参数化的构造函数。 我调用 Room 复制构造函数的一小部分代码:

public TimeInterval(TimeInterval other) throws CloneNotSupportedException 
    
        course_to_room=new ArrayList<>();
        map=new HashMap<>();
        rooms=new ArrayList<>();
        this.day_no=other.day_no;
        this.time_interval=other.time_interval;
        for(Course course:other.course_to_room)
        
            this.course_to_room.add((Course)course.clone());
        

        for(Room room:other.rooms)
        
            Room tempRoom=new Room(room);
            this.rooms.add(tempRoom);
        


        for(Integer key:other.map.keySet())
        
            ArrayList<Course> temp=other.map.get(key);
            ArrayList<Course> newClone=new ArrayList<>();
            for(Course course:temp)
            
                newClone.add(new Course(course));
            


            this.map.put(key, newClone);
        
    

在这里,我正在做精确的代码来复制 Room 对象:

TimeInterval save1=new TimeInterval(time1);

当我从以上 2 个对象(save1 和 time1)打印任何变量时,它们是不同的。

我正在添加输入命令和输出

System.out.println("Old time 1,Room 5 capacity left                           "+save1.R4.getRightCapacity());
System.out.println("Old time 2,Room 5 capacity left "+save2.R4.getRightCapacity());
System.out.println("Old time 2,Room 5 right strength "+save2.R4.getRightStrength());
System.out.println("Old time 1,Room 5 capacity left "+time1.R4.getRightCapacity());
System.out.println("Old time 2,Room 5 capacity left "+time2.R4.getRightCapacity());
System.out.println("Old time 2,Room 5 time 1 right strength "+time1.R4.getRightStrength());

输出:

旧时1号,5号房还剩60人

旧时2,5号房还剩60人

旧时2,房间5右力0

旧时 1,房间 5 剩余容量 0

旧时2,5号房还剩60人

旧时2,房间5时1右力60

【问题讨论】:

您能否更清楚地说明问题是什么,以及您是如何断定存在问题的? 我已经从 save1 和 time1 打印了 rightStrength 变量。 save1 显示 0。time1 显示 60。它处于循环状态,因此 time1 随时间变化,save1 应将此更改的值复制到 rightStrength。但是 rightStrength 仍然是 0。所以,我断定它正在调用参数化构造函数。 如果TimeInterval 上有一个rightStrength 变量,你还没有显示它。请发帖minimal reproducible example。 向 cmets 添加代码格式不正确,请尝试编辑您的问题。 (如果您还提供您使用的打印语句以及您获得的结果和您期望的结果,这将有所帮助。准确有助于 ***。) 您的问题与默认构造函数无关。 【参考方案1】:

Java 不像 C++ 那样拥有复制构​​造函数。

你已经制作了两个构造函数,一个使用房间号和容量,另一个使用现有房间制作一个。您没有默认构造函数。此外,Java 中没有自动使用“复制构造函数”。相反,如果你想创建一个副本,那么你可以通过显式调用你创建的 Room(Room) 构造函数来显式地这样做。

问题是你想让“克隆”方法调用 Room(Room) 构造函数吗?在这种情况下,如果需要,您可以从“克隆”方法内部调用它。

当你说它们不同时,你是什么意思?您是否打印了地址并注意到它们是不同的物理对象?还是说应该相同的参数不一样?

【讨论】:

我已经明确调用了 Room 复制构造函数。我已经提到了那个代码。 for(Room room:other.rooms) Room tempRoom=new Room(room); this.rooms.add(tempRoom); 变量在这2个对象中有不同的值 您可能想改写问题的标题。您的问题似乎与更新其字段的副本有关?我仍然不是 100% 理解您的问题是什么,但我感觉在您的代码中某处您正在更新 rightStrength 值,但它没有以您想要的方式更新? 是的,它正在按照我的意愿进行更新。但是当我复制time1并将其保存到save1时。 time1 显示正确的更新值。但是 save1 显示了我在默认(参数化)构造函数中输入的值【参考方案2】:

我已经解决了这个问题。我在所有构造函数中打印了一些东西并逐行调试。我发现这个语句( TimeInterval save1=new TimeInterval(time1); )导致了这个问题。 我写了我在步骤中找到的内容:

    当 TimeInterval save1=new TimeInterval(time1);开始执行时,它调用了 Room 的参数化构造函数(我错误地称之为默认)。然后调用 Room 的复制构造函数。

    但我希望它只是调用 Room 的复制构造函数。然后,我发现我在 TimeInterval 类的复制构造函数之外创建了一些 Room 对象(不仅仅是引用,而是通过调用 'new' 关键字的整个对象)。

    我将这些行放在了我在 TimeInterval 类的参数化构造函数中创建 Room 对象的位置。

    问题已解决。

    打印错误值的问题:当 TimeInterval 类使用参数化构造函数创建 Room 对象时(对于在 TimeInterval 类的构造函数之外编写的那些行),它将我在 Room 对象中打印的那些变量初始化为默认值(这是0)。然后,它调用 Room 的复制构造函数,只是复制了这些 Room 对象(其变量具有默认值),而不是我想要的那些房间对象的副本。

【讨论】:

以上是关于不调用复制构造函数,但调用默认构造函数 java的主要内容,如果未能解决你的问题,请参考以下文章

为啥在malloc中不调用构造函数? [复制]

为啥在malloc中不调用构造函数? [复制]

如何通过使用自定义构造函数而不调用析构函数来创建具有初始大小的向量? [复制]

对象做函数参数和函数返回值时,调用复制构造函数,构造函数,析构函数的情况

为啥隐式复制构造函数调用基类复制构造函数而定义的复制构造函数不调用?

子类为啥要调用父类的构造函数