• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Explanation to what exactly copy constructors and Deep and Shallow copies are?

 
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Just got done watching this little video on copy constructors on youtube:


And I am left confused as to what they still are. So in the video the guy states that we would like to create two enemy objects. So A = A but the second A is exactly like the first A except it's not it's a copy, making it different. My confusion sets in when he explains the code for the first ninja George which I guess in code looks something like:



Is this code the correct representation of the video? I was really confused by what weapons and tools would be if they aren't primitives or Strings then what else could they be? and should a parameterized constructor be in there somewhere too?


Then Gracie would be like somewhere within the former code and would look like:



That was what he called the "wrong code" because, although name and hitPoints won't point to the same object on the heap since they are immutable the weapons and belt will, which confuses me more about them.

The proper way by what the video said to write a copy constructor for Gracie would be:




What exactly is this whole Deep copy Shallow copy thing about? truly am not understanding the idea here.

What is weapon and tool thing about?

This whole section here I am confused about don't understand a single thing about it:




Please explain
Thank you
 
Rancher
Posts: 1093
29
Netbeans IDE Oracle MySQL Database Tomcat Server C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Justin,

What it comes down to is:

Objects have references and atomics are values. When you have a reference to an object, you are dealing with the object itself, not a new object so if you do this:

Those are two separate Strings, but if you say s1 = s2; Then not only is the value you get when you print each the same, but they both reference exactly the same String object. So you say, Strings are immutable, can't change , so if you change s2 = "Bob and Jim"; What happens to s1 is s1 "Bob and Jim" also, no, because s1 and s2 are only references to what ever you want to tell them they reference. OK, so what about if we say s1=s2+" is cool." because Strings are immutable, you didn't change the String that was referenced by s1 (go back to using our first s1 and s2, but you now have s1 references a new string "Your Sword is cool." and does not have any reference to s2 any longer. Notice s1 still references a String, but now what happened to s2? Nothing. s2 is still the same, but s1 has now been orphaned and is eligible to be garbage collected when Java gets around to it.

So now what? Let's make an object:

OK, now what happens when we instantiate A? A a= new A("boo-hoo"); Well, the variable i , atomic, gets the value of 50 and s gets a new value of "boo-hoo" and "cool" is lost, and can be garbage collected, no longer referenced. What if we do this a.decI(); well a.i becomes 49, but it's an atomic and the value just changes--no new object created, but what if I say a.repI(100); Well, a.i becomes 100, but only the value of the variable changes, it is not an object reference, but an atomic, so just the value in the container i is changed.

I am sure this leaves you with a question of two--ask away.
 
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That was a good tutorial; one tiny nitpick. He said that primitives are immutable, whereas I would say they are independent of each other. If you have two different instances of a class with an int field value 123, then changes to one of them will not change the other.
What it means is that you have to keep digging down into the structure of your object until you reach the place where you are handling primitives or immutable reference types. Immutable types include String and most of the subclasses of Number. Lists and arrays are always mutable reference types, There are ways of copying Lists as I mentioned yesterday. Note the Arrays class has copying methods, but they seem to be shallow copies, so they will be awkward to use for arrays of arrays.
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Les Morgan wrote:. . . Objects have references and atomics are values.

Don't call them atomics, but primitives. Remember that some actions on primitives, e.g. double multiplication, are not atomic.

. . . if you change s2 = "Bob and Jim"; What happens to s1 is s1 "Bob and Jim" also, no, because s1 and s2 are only references to what ever you want to tell them they reference. OK, so what about if we say s1=s2+" is cool." because Strings are immutable, you didn't change the String that was referenced by s1 (go back to using our first s1 and s2, but you now have s1 references a new string "Your Sword is cool." and does not have any reference to s2 any longer. Notice s1 still references a String, but now what happened to s2? Nothing. s2 is still the same, but s1 has now been orphaned and is eligible to be garbage collected when Java gets around to it. . .

Are you sure about that? If you reassign s2, that leaves s1 unchanged.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm still unsure what 'Deep' and 'Shallow' copy are, even after explanation. But in a general sense, I understand it as


So say we start out with our original object 'A' and it has its defined set of attributes then....

Shallow copy - Is when you only copy the references to an object. So it's making a copy of all the references from 'A' to 'B', like simply the addresses. So the address of 'A' and 'B' will be the same, and so they will be pointing to the same memory location and share the same data contents. So then the entire field of the original object get copied. Problem is, if the original object has any references to other objects in its field, then only a reference to an object (not a new object) gets copied. And therefore, if we make any alternations to any of these references to objects the change will persist to the original object and vice versa.

****What I didn't understand in the video is he said that we're trying to make a copy of all things that george has, and since things like String and int are immutable does that mean when we make a copy of them, that all things int and String can be easily transferred over, because they are unchangeable? So for example, hitPoints 42, I think that was transferred to gracie? but then what about String? If String is immutable doesn't that mean when it was transferred over that the name "gracie" was also replaced with the name "george"?****


The work around to the previous problem is Deep copying....

Deep copy - when you copy the actual state of the object to a different object. Create a whole 'new' object that's completely different from the previous. So then it's the process of making a copy of all the members of 'A' and then allocating it into a different memory location for 'B' and then assigning the copied members to 'B'. So....in this way if 'A' for some reason changes or becomes non-existent 'B' will still be valid in memory. Therefore, any changes made to 'B' will make effect changes made to 'A' and vice versa.





So back to the original code with some *updates* to put the concept into action:



Was that correctly written out?


My questions are, why is the copy constructor written ike this:



I understand that to mean the name of new object then applying the general instance var at the top of it, then assigning that to copy.name. What's copy.name referring to? if it's the previous object why is it called "copy.name"? how does it know that "copy" means the previous object and "name" is referring to what the name was for the previous object? like what if we have dozens of copy constructors how would it know which one we were referring to?

Also, I understand that weapon and tool are references to other objects out in the ether. Could someone please write a code snippet to illustrate how those objects might look within the code?


Thank you!
 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have changed your // comment to a /* comment */ because the text was too long.

Forget about “memory locations” because you are writing Java® not C. Talk about objects. You either have the same object referred to, or different objects.
In a shallow copy, you get all the same things copied across. If the original has a reference to object XYZ then the copy will have a reference to object XYZ. Yes, exactly the same object. If the original has the value of an int 123 then the copy will have the same int 123. The difference is that changing that int in the original doesn't affect the value in the copy, and vice versa. You can write i++ as often as you like for one of those ints and the other will never know anything about it. But that doesn't apply to reference types.
If you can change the state of a reference type, then that state forms part of the state of the whole object. If XYZ can change, then both the original and the copy will change.

If you want a deep copy, you have to take a copy of the object XYZ, unless it is immutable. Find yourself a copy of Effective Java™ by Joshua Bloch, and in it you will find a chapter about taking defensive copies.
You have completely misunderstood copy constructors. what you are trying to do is write a constructor, and what you have done is write a factory method, but with no return type, so it won't compile. This is what a copy constructor should look likeNow, you can see that you have a new object with the same contents as the original, in such a way that nothing changing object 1 affects object 2. That is now deep enough. You can go deeper, with this sort of thing, but there is never any need to use that particular bit of code.
Another way to do it is to write a factory method. Change the access modifier on that constructor to private, then write this sort of thing:-In the game example, not only should the Ninja class have a copy constructor, but the Tool (not Tools please) and Weapon classes may also need copy constructors.
 
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To better understand shallow vs deep copy, you need to see the effects of doing just a shallow copy vs doing a deep copy. That's the context that you're missing.

When dealing with primitives, you'll always get true copies, so there should be no problem there. An example of this is your Ninja.hitPoints field.

When dealing with object references, however, mutability of the object being referenced and copied plays a role in deciding whether a shallow copy or a deep copy is appropriate.

When you copy a reference to an immutable object, a shallow copy is sufficient. This applies to references like String and Integer and other the primitive wrapper objects, for example. These cannot be mutated or changed once they are created. An example of this is your Ninja.name field.

No surprises. This is what you'd naturally expect.

Are you with me so far?

It gets a little tricky when you are dealing with mutable objects though. Let's assume that Weapons is a mutable object. That is, after you create it, you can add or remove items from it. Let's just suppose you could do this:


Now suppose you only did a shallow copy of weapons:

Here you've only copied the reference. This means that you would have:

The Ninja objects grace and john refer to the same Weapons object. So if I were to add a new item to john's weapons, grace would see that change too! Surprise!

And if I remove an item from grace's list, that item would be removed from john's list, too:

These two surprises are because john and grace refer to the same mutable Weapons object. In essence, they share the same set of weapons.

If you do a deep copy instead, then you wouldn't get any surprises.

If your mutable objects contain mutable objects which contain mutable objects, etc. then "it's turtles all the way down" and you would have to do deep copies until you get to a point where you're copying immutable object references only. That's the only way you can avoid surprises like what I illustrated above.

Does this help?
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:To better understand shallow vs deep copy, you need to see the effects of doing just a shallow copy vs doing a deep copy. That's the context that you're missing.

When dealing with primitives, you'll always get true copies, so there should be no problem there. An example of this is your Ninja.hitPoints field.

When dealing with object references, however, mutability of the object being referenced and copied plays a role in deciding whether a shallow copy or a deep copy is appropriate.

When you copy a reference to an immutable object, a shallow copy is sufficient. This applies to references like String and Integer and other the primitive wrapper objects, for example. These cannot be mutated or changed once they are created. An example of this is your Ninja.name field.

No surprises. This is what you'd naturally expect.

Are you with me so far?

It gets a little tricky when you are dealing with mutable objects though. Let's assume that Weapons is a mutable object. That is, after you create it, you can add or remove items from it. Let's just suppose you could do this:


Now suppose you only did a shallow copy of weapons:

Here you've only copied the reference. This means that you would have:

The Ninja objects grace and john refer to the same Weapons object. So if I were to add a new item to john's weapons, grace would see that change too! Surprise!

And if I remove an item from grace's list, that item would be removed from john's list, too:

These two surprises are because john and grace refer to the same mutable Weapons object. In essence, they share the same set of weapons.

If you do a deep copy instead, then you wouldn't get any surprises.

If your mutable objects contain mutable objects which contain mutable objects, etc. then "it's turtles all the way down" and you would have to do deep copies until you get to a point where you're copying immutable object references only. That's the only way you can avoid surprises like what I illustrated above.

Does this help?



Aspects certainly were very helpful but you did lose me at certain parts. It got complicated fast because there are some gaps in my knowledge/understanding so some of the examples I didn't get.

I'll start with what I think I understood. Ok, so primitives, String & wrapper objects are always TRUE COPIES because they are immutable, we are golden there, we can shallow copy them just fine. Question. When we copy them into the copy constructor are we copying their references or the actual things themselves like int 42 and String "george"?
Anywho, the problem arises in copy constructors when the constructor is fed in mutable objects. Since they are mutable and tethered through a reference, a change made to the mutable object reference will affect the original, and vice versa.

so when we write something like john.name and we assign it "John"; what exactly is this even doing? pretty fresh to programming.
So we create an object of class Ninja and name it john



then we have



I haven't truly grasped the whole idea behind the right part of the equals side.
Breaking it down:
Ninja mean from the Ninja class, got that.
grace, well that's just the var name
='s is just the assignment operator so we are saying that this variable grace, derived from the ninja class is assigned to what's on the right side.
the right side I don't understand what exactly it's really saying. So 'new' that means a new object

But wouldn't it make more sense to be like:



because isn't that what it's essentially saying?
we are assigning a new object derived from the Ninja class and we're calling it grace then we are assigning that to the constructor Ninja(john). I've never understood the order of words there in Java.


then with:



I don't understand what that piece means, we have the class name out front, so it has something to do with the class and then we are putting in the name john, but why? So is Ninja(); with the parens, is that the constructor? I know things can be put into it, but I don't understand what it means to do that.

I have a lot of other questions but I better start with the basics to build up my understanding.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Justin, I suggest you go through the Java Tutorials to understand the basics of object instantiation before you come back and try to understand the mechanics of copy constructors.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Junilu Lacar wrote:Justin, I suggest you go through the Java Tutorials to understand the basics of object instantiation before you come back and try to understand the mechanics of copy constructors.


I'd like to hear everyone's take on it though. I learn better through communicating about it.
 
Junilu Lacar
Sheriff
Posts: 17644
300
Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Justin Robbins wrote:

Junilu Lacar wrote:Justin, I suggest you go through the Java Tutorials to understand the basics of object instantiation before you come back and try to understand the mechanics of copy constructors.


I'd like to hear everyone's take on it though. I learn better through communicating about it.


While folks around here can be very patient with beginners, there's also a limit to that patience. You already got a few takes on it. You're going to have to do some of the legwork yourself.

I'll give you a couple more things to think about:

1. What makes sense to you doesn't necessarily align with what the language creators/designers thought made sense. In fact, your suggestion that this

makes sense, doesn't. The left side is the thing that gets assigned to; it's the thing that receives the value. The right side is what gets assigned. You read the assignment statement like this: The Ninja variable "grace" is assigned a reference to a new instance of Ninja that copies its values from the existing Ninja object, john. In code, that is:

If you want to step through it even slower, you would go like this: Declare a variable 'grace' which will reference a Ninja object. Now create a new Ninja object and have it copy its values from the Ninja object, john. Now make the variable grace reference that new Ninja object.

As for what goes on in assignments statements, I think you're overthinking all this. All it really is is taking the value of something and giving it a "label" (the variable name) that you can use to refer to that value. In the case of object references, you are taking the value of the object reference and assigning it to a variable. In the case of a primitive, you are taking the value of the primitive and assigning it to a variable.

Go out and experiment for yourself. That's the best way to learn. You can't learn to swim by asking people to describe to you what the water is like and what it feels like to float. You have to get into the water and paddle around yourself.
 
Justin Robbins
Ranch Hand
Posts: 121
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So when we have something like:



Could it also be said in English like...the gracie variable IS a new object from the Ninja class which copies its values from the Ninja object john.

So then the piece that says Ninja(); that's like a piece which initializes some or all of the instance members defined earlier. So the parens can take in different data types which are to be fed into a say the constructor, copy constructor et cetera depending on the what exactly is put within those parens. And what is put inside of those parens is what will establish all the attributes values for that object. So here we are putting in the word john into the parens, so when we do that it means to copy exactly the values of johns attributes values and paste them into the attributes for this new object called gracie. And when we don't pass anything into those parens it will automatically go to the default constructor. Is that right? Also, is there a name for what that piece is called where it's Ninja(); ?

With this code:


Here that object john, or reference to an object of the Ninja class does not take in anything into its parens so all its attributes values would be defined by a default constructor. When that part john.name = "john"; is written, is that like manually setting up the values? so like taking the object (.) instance variable then assigning that to something, is that what its doing?

then here:


So we are passing in john, so is the Ninja() called a copy constructor? because I though the copy constructor was the actual special method defined outside of the instantiation block. Or does the copy constructor simply run the line of code where the object of what's being passed in is, and then copy and paste its attributes to the one calling it.

But then that gets overrode when grace.name = "Grace"; is written.

So then everything is peachy once the print statements run, but if grace.name = "Grace"; wasn't added then it would have printed both John.


Is that right?

 
Campbell Ritchie
Marshal
Posts: 79151
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Justin Robbins wrote:. . . what I think I understood. Ok, so primitives, String & wrapper objects are always TRUE COPIES because they are immutable, . . . are we copying their references or the actual things themselves like int 42 and String "george"?

Only in the case of primitives do you copy the actual value (42, 42.0, false, etc). In the case of reference types, mutable or immutable, you always copy the reference. The value "George" never lives inside the object; it lives on the heap like all other objects (beware oversimplifications). The object with that field keeps a record of the location of that reference.

Anywho, the problem arises in copy constructors when the constructor is fed in mutable objects. Since they are mutable and tethered through a reference, a change made to the mutable object reference will affect the original, and vice versa.

Not quite. A change to the object reference will change the state of one classWhen you change an object by reassigning it, you are dissociating the new object from all other objects. There is the risk that you are setting up two references to the same object:-That is not what usually happens; each Ninja has to sharpen their own Sword. You should arrange the methods to look like n1.sharpenWeapon() and if (n1.hasSharpWeapon())... Far better than my multiple dots above

so when we write something like john.name and we assign it "John"; what exactly is this even doing? pretty fresh to programming.
So we create an object of class Ninja and name it john

Inside the current method, yes, you instruct the JVM to create an object with the new operator. The constructor is called immediately thereafter so as to make sure all the fields are correctly initialised. The JVM then finds the memory location where that object can be found (another oversimplification) and writes that memory location into the object's field. It is better not to let the fields be seen outwith the class, so they should have private access. But if you assign them in a set methodYou get a new reference to a different String under the title of name, and you assign that to the name field called this.name. You are replacing the old memory location/reference with a new one pointing to (probably) a different object. The old reference disappears into cyber‑limbo never to be seen again, unless you have a copy of that reference elsewhere,

. . . . . .. . .

The new keyword is an operator, the same way the + and − are operators. It has a particular type of operand, and it has to be used in a particular order. You write 1 + 2 not + 1 2 which is out of order (unless you are writing LISP). There might be languages where you write new Ninja grace = Ninja(john), but Java® doesn't work like that. The new operator followed by the class name creates the object. The () after the class name call that constructor, with whatever information you are passing as arguments. You can do several things with the reference which you know the JVM will return:-
  • 1: You can assign it to a variable. That uses the = operator, and that is what you have shown in your earlier post
  • 2: You can pass it directly to some method or other, e.g. myList.add(new Ninja(...));
  • 3: You can call a method on it, e.g. new NinjaDemo().startGame(); That is sometimes all that is necessary.
  • 4: You can leave it. You would think that would cause the object to disappear, but sometimes you set up a GUI in the constructor so you only need to say, new MyGUI(); and it will all appear on screen.

  • You know a constructor is a copy constructor because you have read the constructor or its documentation. Remember the String copy constructor I showed you earlier? If you click that link you will find that it makes a copy of the String passed as an argument. The fact that you never need that sort of copy constructor for Strings is irrelevant: that is a copy constructor.
     
    Justin Robbins
    Ranch Hand
    Posts: 121
    2
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Junilu Lacar wrote:



    Ok after carefully reviewing all that I think it finally makes sense now. A copy constructor is a way to tell Java, "Hey, if another object is passed into an objects parameters then run the copy constructor" and then the copy constructor is what specifies certain things, specifically here it says to free separate memory for weapons. So anytime the CC is called it will create a separate memory for that object, so that no two "character" objects will share the same weapons object. It creates separate memory for those mutable object instance variables, so we would also have to create a stipulation in the copy constructor for tools as well. Which makes sense because we don't want the same objects to have the same inventory of objects we want them to be separated so that they don't persist & influence one another. So overall, deep copying is a way of explicitly allocating memory for specific mutable objects of any "character" object when the CC is called. And we only have to explicitly point out those mutable objects, the immutables one can just be straight shallow copied so no need for extra typing or memory for them into the CC.


    The only thing that I think I'd need further explaination on is:


    and



    Could you please give the English translation of them.

    I'm thinking it's something like "This current objects weapons IS a new Weapon...." then I get kind of lost because I think of stuff like a variable type and not sure what it means for it to the in copy.weapons into it's parameters.
    similar confusion for the second line.


    Thank you so much for your help it's opened my eyes about deep and shallow copying.
     
    Junilu Lacar
    Sheriff
    Posts: 17644
    300
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Justin Robbins wrote:
    The only thing that I think I'd need further explaination on is:



    In plain English:

    1. Instantiate an object
    2. Using the Weapons constructor that takes a Weapons object, passing in
    3. the weapons attribute of
    4. the Ninja object referenced by the copy variable
    5. and assign a reference to that new Weapons instance
    6. to the weapons attribute/field
    7. of the current Ninja object

    The reasonable expectation you'd have of the Weapons(Weapons copy) constructor (2) is that it will appropriately copy the Weapons object passed to it as a parameter. That is, after this line is executed, the current Ninja object will have a separate but similar set of weapons that the Ninja object referenced by the copy variable has. If the copy object has three weapons, then the current object will have copies of those same three kind of weapons. This is what a "deep" copy is about.


    1. Instantiate an object
    2. Using the Weapons constructor that takes no parameters
    3. and assign a reference to that new Weapons instance
    4. to the weapons attribute/field
    5. of the Ninja object referenced by the variable john

    Since the Weapons() constructor (2) here does not take any parameters, the reasonable expectation is that the Weapons object that is created is empty, it does not contain any weapons. That is, the Ninja object, john, is only able to do empty-handed combat.
     
    Junilu Lacar
    Sheriff
    Posts: 17644
    300
    Mac Android IntelliJ IDE Eclipse IDE Spring Debian Java Ubuntu Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    This explains the difference between a "no-args constructor" and a "default constructor"


    All three of the above classes each have exactly one constructor.

    Foo does not have an explicit constructor. By default, the compiler will provide one that takes no arguments (a no-args constructor). This is the default constructor and it will always be a no-args constructor.

    Bar has an explicit constructor that takes no arguments. This constructor IS a no-args constructor but it is NOT a default constructor because the compiler did not provide it.

    Baz has an explicit constructor that takes an int parameter. This constructor obviously IS NOT a no-args constructor NOR is it a default constructor because the compiler did not provide it.
     
    Campbell Ritchie
    Marshal
    Posts: 79151
    377
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Justin Robbins wrote:. . . I think it finally makes sense now.

    Yes. I think you are right. And congratulations on the cow for the effort you have put into this thread and for asking a slightly unusual and veru interesting question question.

    A copy constructor is a way to tell Java, "Hey, if another object is passed into an objects parameters then run the copy constructor" and then the copy constructor is what specifies certain things, specifically here it says to free separate memory for weapons.

    You are still going on about memory; it would be better to think, “Create a new object.”

    So anytime the CC is called it will create a separate memory for that object, so that no two "character" objects will share the same weapons object.

    Assuming the CC is written that way, yes.

    It creates separate memory for those mutable object instance variables, so we would also have to create a stipulation in the copy constructor for tools as well.

    Do you really mean stipulation? You can write stipulations in the documentation comments or you can write instructions (=statements) in the body of the method/constructor.

    . . . So overall, deep copying is a way of explicitly allocating memory for specific mutable objects of any "character" object when the CC is called. And we only have to explicitly point out those mutable objects, the immutables one can just be straight shallow copied so no need for extra typing or memory for them into the CC.

    Yes

    The only thing that I think I'd need further explaination on is:
    . . .

    Consider the = operator as working from right to left. That statement means something like this:-
  • 1: Find the weapon field because it is preceded by this. (rather than the local variable or parameter). We already know its type, so what we are looking for is a number which allows you to find the memory location of a Weapon object.
  • 2: The = operator looks for what is to its right and applies it to whatever is to its left. So the JVM will look for whatever is to the right of the =
  • 3: The new operator followed by the name of a class creates an instance of that class and provides a reference to that object.
  • 4: You must specify which constructor to use: the (copy.weapon) tells the JVM it is passing an instance of the same class, so it runs the copy constructor. It doesn't actually “know” it is a copy constructor, but whoever programmed it knows that. Remember you are only allowed one constructor per set of parameters, so you cannot compile two copy constructors in the same class.
  • Thank you so much for your help it's opened my eyes about deep and shallow copying.

    That's a pleasure
    reply
      Bookmark Topic Watch Topic
    • New Topic