1
public MyConstructor(MyConstructor mc){
   this.setId(mc.getId());
   this.setName(mc.getName());
}

Here why do we need to set the value in constructor by getting its getter method. Is there any special purpose behind this ?

user1991
  • 21
  • 7
  • 1
    Hi, the only reason is if accessor (getter/setter) have some logic. – Vyncent Mar 20 '15 at 10:13
  • 1
    you don't use the getters from the object you are creating (`this`) but the one from the object you are copying (`mc`) – jhamon Mar 20 '15 at 10:13
  • The constructor code could be written as `this.id = mc.id;` (assuming a backing field called `id`) if you wanted. Or `setId(mc.id)`. Or `setId(mc.getId())`. – Jon Skeet Mar 20 '15 at 10:14
  • In this case `this` is optional, but if you would have `public Constructor(int x){ this.x = x; }` then you need `this` to determine which `x` is field and which is argument of constructor. – Pshemo Mar 20 '15 at 10:15
  • To add to Vyncent's comment: ... or if they might get some logic in the future (the probability depends on how you expect the class to be developed/used). If you directly use the form `this.id = mc.id` you'd have to change the constructor as well when you decide that either setter or getter need some additional logic. – Thomas Mar 20 '15 at 10:15
  • @JonSkeet If the class isn't final, direct field copying could break the semantics. – chrylis -cautiouslyoptimistic- Mar 20 '15 at 10:49
  • Since nobody's mentioned it, this is called a *copy constructor*. – chrylis -cautiouslyoptimistic- Mar 20 '15 at 10:50
  • @chrylis: Indeed (assuming getId and setId also aren't final, of course). – Jon Skeet Mar 20 '15 at 10:50

4 Answers4

1

As already pointed out in the other answers, this sort of constructor mainly is intended for cloning objects, and is sometimes referred to as copy constructor

As Joshua Bloch suggests in his Book "Effective Java", Item 11, such a constructor should usually be preferred over implementing the clone() method, because the clone() method has some issues (see the book or corresponding stackoverflow questions for details).

There is no striking reason to implement it exactly like that - thus, one does not really need it in exactly this form. As mentioned in the comments, one could (most likely) alternatively write it as

public MyConstructor(MyConstructor mc){
    this.id = mc.getId();
    this.name = mc.getName();
}

or

public MyConstructor(MyConstructor mc){
    this.setId(mc.id);
    this.setName(mc.name);
}

or

public MyConstructor(MyConstructor mc){
    this.id = mc.id;
    this.name = mc.name;
}

The author here chose to use the nested set(mc.get()) approach. It has the potential advantage that it solely relies on the interface that is defined in terms of get/set methods, and thus may be more robust against changes.

One could argue about whether this is a good practice in general, but I think that for a copy constructor, it nicely and clearly states: "This object is initialized here, solely based on (and exactly like) the given object".


Side note: Cloning an object and giving the clone the same ID most likely defeats the purpouse of an ID - but there might be cases where this is appropriate

Marco13
  • 53,703
  • 9
  • 80
  • 159
0

Consider cloning objects for a moment, but this is not cloning. If you come across a situation where you have a MyConstructor(type) object in your hand and you need to create another new object with the same object type MyConstructor. So, in your MyConstructor class, you need a constructor like above.

There you take the object what you had in your hand and take the id of that object, when you create your brand new second object

Jude Niroshan
  • 4,280
  • 8
  • 40
  • 62
0

The purpose behind a constructor like that, is mostly for cloning. Suppose you need to assign the value of one object to another and not the reference, this will work just fine.

Is already discussed here: How do I copy an object in Java?

Community
  • 1
  • 1
Mosd
  • 1,640
  • 19
  • 22
0

This is important to consider particularly if your class will be derived by a (sub) class.

public class Child extends Parent {

    private int id;
    private String name = "Child";

    ...
    // getter and setters...
}


public class Parent {

    private int id;
    private String name = "Parent";

    public Parent(Parent parent) {
        this.setId(parent.getId());
        // option#1
        this.setName(parent.getName());
        // option#2
        // this.name = parent.name;
    }
    ...
    // getter and setters...
}

Sample main:

public class Main {
    public static void main(String ...strings ) {

        Parent parent = new Parent();
        Child child = new Child();

        Parent parent2 = new Parent(child);
        System.out.println(parent2.getName());

    }
}

Output:

Child

But if we use the Option#2 this.name = parent.name instead the output will be

Parent
owenrb
  • 535
  • 2
  • 7