I've been programming Java for 2 years now, and I have encountered a problem where I couldn't understand and differentiate class, reference, and an object.
I am not sure if a class or reference are the same, though I have an idea of what an object is.
Can someone differentiate in a complete manner what classes, references, and objects are?
All I know is that a class is more like a template for an object (blueprint to a house where the class is the blueprint and the house is an object).
If you like housing metaphors:
a class is like the blueprint for a house. Using this blueprint, you can build as many houses as you like.
each house you build (or instantiate, in OO lingo) is an object, also known as an instance.
each house also has an address, of course. If you want to tell someone where the house is, you give them a card with the address written on it. That card is the object's reference.
If you want to visit the house, you look at the address written on the card. This is called dereferencing.
You can copy that reference as much as you like, but there's just one house -- you're just copying the card that has the address on it, not the house itself.
In Java, you can not access objects directly, you can only use references. Java does not copy or assign objects to each other. But you can copy and assign references to variables so they refer to the same object. Java methods are always pass-by-value, but the value could be an object's reference. So, if I have:
Foo myFoo = new Foo(); // 1
callBar(myFoo); // 2
myFoo.doSomething() // 4
void callBar(Foo foo) {
foo = new Foo(); // 3
}
Then let's see what's happening.
Several things are happening in line 1. new Foo() tells the JVM to build a new house using the Foo blueprint. The JVM does so, and returns a reference to the house. You then copy this reference to myFoo. This is basically like asking a contractor to build you a house. He does, then tells you the house's address; you write this address down.
In line 2, you give this address to another method, callBar. Let's jump to that method next.
Here, we have a reference Foo foo. Java is pass-by-value, so the foo in callBar is a copy of the myFoo reference. Think of it like giving callBar its very own card with the house's address on it. What does callBar do with this card? It asks for a new house to be built, and then uses the card you gave it to write that new house's address. Note that callBar now can't get to the first house (the one we built in line 1), but that house is unchanged by the fact that a card that used to have its address on it, now has some other house's address on it.
Back in the first method, we dereference myFoo to call a method on it (doSomething()). This is like looking at the card, going to the house whose address is on the card, and then doing something in that house. Note that our card with myFoo's address is unchanged by the callBar method -- remember, we gave callBar a copy of our reference.
The whole sequence would be something like:
Ask JVM to build a house. It does, and gives us the address. We copy this address to a card named myFoo.
We invoke callBar. Before we do, we copy the address written on myfoo to a new card, which we give to callBar. It calls that card foo.
callBar asks the JVM for another house. It creates it, and returns the new house's address. callBar copies this address to the card we gave it.
Back in the first method, we look at our original, unchanged card; go to the house whose address is on our card; and do something there.
When you code, you build an
Instance (occurrence, copy)
of an
Object
of a said
Class
and keep a
reference
to it, so you can call its methods.
Also, some OOP basics: Classes, Object, Instance, and Reference.
In the book "Thinking in Java" from Bruce Eckel it has been described perfectly:
"You might imagine a television (the object) and a remote control (the reference). As long as you’re holding this reference, you have a connection to the television, but when someone says, “Change the channel” or “Lower the volume,” what you’re manipulating is the reference, which in turn modifies the object. If you want to move around the room and still control the television, you take the remote/reference with you, not the television.
Also, the remote control can stand on its own, with no television. That is, just because you have a reference doesn't mean there’s necessarily an object connected to it. So if you want to hold a word or sentence, you create a String reference:
String s;
But here you’ve created only the reference, not an object. If you decided to send a message to s at this point, you’ll get an error because s isn’t actually attached to anything (there’s no television). A safer practice, then, is always to initialize a reference when you create it:
String s = "asdf";
However, this uses a special Java feature: Strings can be initialized with quoted text. Normally, you must use a more general type of initialization for objects.
When you create a reference, you want to connect it with a new object. You do so, in general, with the new operator. The keyword new says, “Make me a new one of these objects.” So in the preceding example, you can say:
String s = new String("asdf");
Not only does this mean “Make me a new String,” but it also gives information about how to make the String by supplying an initial character string.
Of course, Java comes with a plethora of ready-made types in addition to String. What’s more important is that you can create your own types. In fact, creating new types is the fundamental activity in Java programming."
Suppose you write there two lines of code:
Engine app1 = new Engine(); //LINE 1
Engine app2 = app1; //LINE 2
In line 1, Engine is a class, its a blue-print basically.
new Engine() is the instance that is made on the heap.
You are refering that instance by using app1 and app2 in your code.
So app1 and app2 are the references.
When you create an object, what happens behind the scene is that a piece of memory is reserved for containing that object. This could be anywhere in the great big memory landscape; it's up to the operating system and the compiler, and you don't really have any control or knowledge of where it ends up.
Ask yourself, then, how do you use that object if you don't know where in memory it is? How can you read a value from it if you don't know where that value is stored? This is what references do for you. They are a way of keeping in touch with the object. It's a little string attached to the balloon that is a reference.
You use the reference to say that "I want to touch this object now!", or "I want to read a value from this object!".
========= Class and Object ===========
Class => ex: Person (More like imagination)
Object => ex: John, Mike (Real person)
=========== Reference ============
ex:
Television tv1; - (Television is a class, tv1 is a remote controller without Television)
Television tv2 = new Television(); - (Now tv2 remote controller has a Television)
tv1 = tv2; - (Now tv1 and tv2 can control same Television)
Television tv3 = new Television(); - (tv3 is a new remote controller with new Television)
Class:
Structure or BluePrint
Object:
Physical Manifestation
Reference:
Address of Object
Class is a template, you are right. It is some knowledge about data structure. Object is that structure instance in memory. Reference is a memory address of that instance.
If by Object you meant the java identifier, then Object is the basic class for all complex Java classes.
Object is the run time representation of the Classdefinition. And the name with which you use the object is called the reference (as it references the actual object location in memory )
example
MyClass ref = new MyClass();
Here, MyClass is (contains) the class definition.
new MyClass() creates an object for this class (done only during execution, hence runtime representsion)
ref is the name you use to work on the class object, is the reference.
Class : Used to define a real life entity into a programming environment.
Any real life entity having at least one property and a corresponding behaviour can be considered as a class. Lets take an example of a Car, it is having a property accelerator which helps the car to move and to control its speed. The corresponding behaviour is acceleration, which is directly proportional to the push applied to the accelerator.
class Car {
private String tier;
private String tierFriction;
private double weight;
private double gasFedToEngine;
}
The above class shows some properties of a Car, on which its acceleration depends. Behaviour (method in the class) always depends on the property(s) (global attribute(s) of the class). Now if you want more details you can define Tier as another entity, then the definition will look like
class Tier {
private String tierMaterial;
private String tierFriction;
private double weight;
private double tierDiameter;
}
class Car {
private Tier tier; // getting all properties of Tier here itself
private double weight;
private double gasFedToEngine;
}
Object : Used to define various flavours of an Entity and to perform data manipulations on them separately.
Now we have defined an entity to our program, say we are having a showroom of used cars, having cars of different companies. So each car becomes an object of our entity. Objects can be Audi, Nissan, Ferrari etc. So after opening the showroom we add cars to it like this
static List<Car> showroomCars = new ArrayList<Car>();
public boolean addCarToShowroom() {
Car carNissan = new Car(); // always creates a new objects and allocates some memory in heap
carNissan.setName("Nissan");
carNissan.setColor(RED);
carNissan.setWeight(300);
showroomCars.add(carNissan);
Car carAudi = new Car();
carAudi.setName("Audi");
carAudi.setColor(BLACK);
carAudi.setWeight(270);
showroomCars.add(carAudi);
}
So now two new cars are added to the Showroom, one of Nissan and another one of Audi, each having their own specific attribute values.
Class only gives definition, manipulation is done on Object, for doing manipulation on any Class, object should be created. Every time an object is created to a class all its non-satic(instance) variables will load into memory with their respective default values.
Reference : Used to address an object
When we say Car carAudi = new Car(); we define a new object to Car and a memory location is assigned for that object. The reference variable carAudi holds the memory address of that object. Object is never accessed directly by user, neither its memory location. That's where reference variable has significance, its stores the hexadecimal format of memory location. If we want to do modifications on an object do with the help of reference not directly.
An object can have any number of reference, but a reference can point only to one object at a time.
class Car {
void test() {
Car car1 = new Car(); // (1)
Car car2 = new Car(); // (2)
car2 = car1;
/**
Says that car2 should point to where car1 points, so now both points to first object of Car
But for this car2 has to loose its current object-(2), making it an Abandoned object (An object with no active reference from the stack).
**/
}
}
In Real world, Object is a material thing that can be seen and touched in this universe.
In Programming, Objects are same but those are stored or trapped inside a memory like when any object is being created. it will create in the RAM(Memory). So, As a human we will not be able to see it or touch it but it do exist in the memory somewhere.
So, we don't care about how system is creating or destroying objects, rather we will see how to handle it using programming.
In order to create an object, Programming language provide's us syntax format's which we can use handle these objects.
Now, How you will define what object you want to create like if you want to create a customize new car then you have to provide your requirements to the manufacturer right?.
Same way in programming, class is used. The class is a blueprint which will define how object should look like/what all data it will store and what all operation it will do. It doesn't exist in the memory and just used to define the requirements for creating an object.
Let's take an example of student:
//We have a Student class. Below are some attributes which we will use:
class Student
{
string Name;
int Age;
string Address;
}
Now, Above Student doesn't really exist. This is only a blue print of how student will be. If we need to create a student then we call it creating a object and below is the format to create one student.
Student student=new Student();
Now, 1 student object has been created in the memory which can be used to set any name/age/address and get the same information as shown below:
static void Main(string[] args)
{
Student student = new Student();
student.Name = "Vivek";
student.Age = 24;
student.Address = "Address";
Console.Write("Student Name is " + student.Name + " whose age is " + student.Age + " and he/she stays at " + student.Address);
}
Now, Assume you want to provide some work to Student, How will you do it?
//By writing a function/method and write the code which student should handle as below:
class Student
{
public string Name;
public int Age;
public string Address;
public void Run()
{
//Write some code
}
public void Walk()
{
//Write some code
}
}
Above one is just an example as student will not run in the memory, So, Code which you have to write is C# code only or whatever programming language which you are using to write code. Like do some operation with C#.
Now, I would like to highlight that:
if you see in the real world. Student does not only contain Name/Address/Age but student also have other attributes like Mother Name/Father Name/Passport etc. In addition to normal attributes, We can also add body parts like Brain/Heart/Legs etc.
So, Class Student can be more complex if you add all attributes to it.
Example: Your customize car will not customize all parts of your car. You have to use exisiting parts like wheels/tier/Air conditioner etc. So, Classes can use exisiting classes/struct/methods/fields etc. in order to achieve the requirement. As you can see below that class is using other classes/struct/methods/fields etc. in order to achieve the requirements:
//String is also class which represents text as a sequence of UTF-16 code units
public string Name;
//Integer is a struct which represents a 32-bit signed integer
public int Age;
//String is also class which represents text as a sequence of UTF-16 code units
public string Address;
Everything in Java is associated with class objects and classes, including attributes and methods. Ex: a car is an object in real life. The car has attributes, such as weight and color, and methods, such as drive and brake. A Class is like an object constructor or a "blueprint" for creating objects.
A reference is an address that indicates where an object's variables and methods are stored. You aren't actually using objects when you assign an object to a variable or pass an object to a method as an argument.
Related
I have to write a code that keeps record of competitors participating to different events.
Competitor is a class with the following attributes: name, surname, age, id.
Event is a class with the following attributes: name, date, a list of competitors.
Professor then says that I must also keep track of whether a competitor has confirmed their participation to the event or not. That is a competitor could be listed in an event but may not have confirmed their participation to it yet. How to implement this is up to me.
So, keeping in mind that a competitor may participate to multiple events, I would like to avoid creating a Competitor object for one same person for each event he's taking part in.
I was thinking of something that sounds optimal in C but that I can't translate into Java: I would like to create a new class, CompetitorInEvent, that would hold all the information contained in Competitor plus the boolean representing the confirmation to the event (which event is not stated, because the list such competitorInEvent belongs to already tells it).
And as a consequence I would turn the list of competitors into a list of competitors-in-event.
CompetitorInEvent shouldn't extend Competitor, but rather hold a reference to a Competitor object. In C, I would promise to only access this reference for reading and never for writing and I would have the struct CompetitorInEvent storing only an address and a boolean (or rather a short in C). This seems correct to me because I'm not instancing same real world objects multiple times or wasting memory. But is there a way to achieve these same goals in Java? I'm aware that pointers are not available.
Java holds references to objects, which you can think of as pointers. You just cannot do any arithmetic on references like you can to pointers in C. So this code shows two CompetitorInEvents referencing the same Competitor:
class CompetitorInEvent {
private Competitor competitor;
public CompetitorInEvent(Competitor competitor) {
this.competitor = competitor;
}
}
Then to use this:
Competitor aCompetitor = new Competitor();
CompetitorInEvent event1 = new CompetitorInEvent(aCompetitor);
CompetitorInEvent event2 = new CompetitorInEvent(aCompetitor);
Now there is only one Competitor instantiated, with 3 references to it: The local variable aCompetitor and the two events. Note that Java maintains reference counts to the object, and will not garbage-collect (destroy) aCompetitor until the local variable goes out of scope (or is reassigned to another reference), and the two CompetitorInEvent objects are both destroyed/garbage-collected.
UPDATE
public Fish mate(Fish other){
if (this.health > 0 && other.health > 0 && this.closeEnough(other)){
int babySize = (((this.size + other.size) /2));
int babyHealth = (((this.health + other.health) /2));
double babyX = (((this.x + other.x) /2.0));
double babyY = (((this.y + other.y) /2.0));
new Fish (babySize, babyHealth, babyX, babyY);
}
return null;
}
When new Fish is called, is there a new instance of Fish floating around somewhere without a reference or have I just allocated memory for a new Fish without actually instantiating it?
Can I get the new Fish call to create an actual instance of the Fish with a unique reference name other than iterating through a loop?
When new Fish is called, is there a new instance of Fish floating around somewhere without a variable name or have I just allocated memory for a new Fish without actually instantiating it?
A new Fish object will be created, and will be garbage-collected since there is no reference to it.
The garbage collection will take place (sometime) after the constructor of Fish is done.
In your case that doesn't make much sense, but sometimes it does, if instantiating an object will start a new Thread or run some other routines that you want to be run only once.
If I have only allocated memory or there is a Fish without a name, how can I get the new Fish call to create an actual instance of the Fish with a unique variable name?
This is not very clear. But I sense that you just want to return new Fish(...); and assign it to a variable yourself where you call it, something like:
Fish babyFish = femaleFish.mate(maleFish);
"have I just allocated memory for a new Fish without actually instantiating it?"
No. The instance is initialized (the constructor is executed), but if no reference is kept for this instance it will eventually be garbage collected. Keep in mind that a reference can be kept even if your code doesn't do so, for example if the constructor puts this in some static variable.
The following figure's explanation really helped me when I had confusion in the beginning and I hope will help you as well.You can think of Employee as Fish here.
In your case you created a new Fish() object locally inside a method, so the lifetime of that should be assigned locally as well.The garbage collector always looks for unused objects and will identify this suitable for collection as soon as your method exits,along with other locals defined inside the method.
You are returning null, so this method can not be treated as factory method structure since it does not return an instance.I am not sure what you mean by :
Can I get the new Fish call to create an actual instance of the Fish with a unique reference name other than iterating through a loop?
But I think you asked if you can use the exact new Fish() that is inside the method.The short answer is: no. Although you can definitely create another new Fish() but you need a reference variable to retrieve that address or you can return the instance for the method instead of null,which will be a static factory method and is known as a good practice when you want to separately name your constructors.
In a more specific manner to answer both of your updated questions:
1)You did created a new object when you wrote new Fish() but you did not create a reference variable to really retrieve that object information.It's like you have built a house but you don't know the address of the house.Then you can never get to the house. What will happen is because of the lack of retrieval process, this object will be identified as unused by the garbage collector and hence it will be collected.
2)Since there is no reference/pointer or anything to get the information stored in the new object, you cannot retrieve the exact new Fish() inside the method but you can certainly create another object with a reference variable if you really wish to retrieve the information stored in the object.
Lastly, although it is mainly written for C language usage, the following document by Nick Parlante of Stanford University does an exceptional job in explaining references, stack,and heap memories.Click here.
First, let me clear up some confusion in your terminology: An object doesn't have a name. A variable has a name, but you can have many variables of different names all referring to the same object. Having a named variable reference the object does not mean the object has a name.
If you do new Fish() but don't assign the new reference to anything, the new object will be unreachable as soon as the constructor returns.
There is no way to recover that reference, and the object will be unallocated by the next Garbage Collection run.
This question already has answers here:
What are classes, references, and objects?
(12 answers)
Closed 6 years ago.
Exactly what are the differences between variables, objects, and references?
For example: they all point to some type, and they must all hold values (unless of course you have the temporary null-able type), but precisely how are their functions and implementations different from each other?
Example:
Dog myDog = new Dog(); //variable myDog that holds a reference to object Dog
int x = 12; //variable x that hold a value of 12
They have the same concepts, but how are they different?
(Just to be clear, the explanation I'm giving here is specific to Java and C#. Don't assume it applies to other languages, although bits of it may.)
I like to use an analogy of telling someone where I live. I might write my address on a piece of paper:
A variable is like a piece of paper. It holds a value, but it isn't the value in itself. You can cross out whatever's there and write something else instead.
The address that I write on the piece of paper is like a reference. It isn't my house, but it's a way of navigating to my house.
My house itself is like an object. I can give out multiple references to the same object, but there's only one object.
Does that help?
The difference between a value type and a reference type is what gets written on the piece of paper. For example, here:
int x = 12;
is like having a piece of paper with the number 12 written on it directly. Whereas:
Dog myDog = new Dog();
doesn't write the Dog object contents itself on the piece of paper - it creates a new Dog, and then writes a reference to the dog on that paper.
In non-analogy terms:
A variable represents a storage location in memory. It has a name by which you can refer to it at compile time, and at execution time it has a value, which will always be compatible with its compile-time type. (For example, if you've got a Button variable, the value will always be a reference to an object of type Button or some subclass - or the null reference.)
An object is a sort of separate entity. Importantly, the value of a variable or any expression is never an object, only a reference. An object effectively consists of:
Fields (the state)
A type reference (can never change through the lifetime of the object)
A monitor (for synchronization)
A reference is a value used to access an object - e.g. to call methods on it, access fields etc. You typically navigate the reference with the . operator. For example, if foo is a Person variable, foo.getAddress().getLength() would take the value of foo (a reference) and call getAddress() on the object that that reference refers to. The result might be a String reference... we then call getLength() on the object that that reference refers to.
I often use the following analogy when explaining these concepts.
Imagine that an object is a balloon. A variable is a person. Every person is either in the value type team or in the reference type team. And they all play a little game with the following rules:
Rules for value types:
You hold in your arms a balloon filled with air. (Value type variables store the object.)
You must always be holding exactly one balloon. (Value types are not nullable.)
When someone else wants your balloon, they can blow up their own identical one, and hold that in their arms. (In value types, the object is copied.)
Two people can't hold the same balloon. (Value types are not shared.)
If you want to hold a different balloon, you have to pop the one you're already holding and grab another. (A value type object is destroyed when replaced.)
Rules for reference types:
You may hold a piece of string that leads to a balloon filled with helium. (Reference type variables store a reference to the object.)
You are allowed to hold one piece of string, or no piece of string at all. (Reference type variables are nullable.)
When someone else wants your balloon, they can get their own piece of string and tie it to the same balloon as you have. (In reference types, the reference is copied.)
Multiple people can hold pieces of string that all lead to the same balloon. (Reference type objects can be shared.)
As long as there is at least one person still holding the string to a particular balloon, the balloon is safe. (A reference type object is alive as long as it is reachable.)
For any particular balloon, if everyone eventually lets go of it, then that balloon flies away and nobody can reach it anymore. (A reference type object may become unreachable at some point.)
At some later point before the game ends, a lost balloon may pop by itself due to atmospheric pressure. (Unreachable objects are eligible for garbage collection, which is non-deterministic.)
You can think of it like a answering questions.
An object is a what...
It's like any physical thing in the world, a "thing" which is recognizable by itself and has significant properties that distinguishes from other "thing".
Like you know a dog is a dog because it barks, move its tail and go after a ball if you throw it.
A variable is a which...
Like if you watch your own hands. Each one is a hand itself. They have fingers, nails and bones within the skin but you know one is your left hand and the other the right one.
That is to say, you can have two "things" of the same type/kind but every one could be different in it's own way, can have different values.
A reference is a where...
If you look at two houses in a street, although they're have their own facade, you can get to each one by their one unique address, meaning, if you're far away like three blocks far or in another country, you could tell the address of the house cause they'll still be there where you left them, even if you cannot point them directly.
Now for programming's sake, examples in a C++ way
class Person{...}
Person Ana = new Person(); //An object is an instance of a class(normally)
That is to say, Ana is a person, but she has unique properties that distinguishes her from another person.
&Ana //This is a reference to Ana, that is to say, a "where" does the variable
//"Ana" is stored, wether or not you know it's value(s)
Ana itself is the variable for storing the properties of the person named "Ana"
Jon's answer is great for approaching it from analogy. If a more concrete wording is useful for you, I can pitch in.
Let's start with a variable. A variable is a [named] thing which contains a value. For instance, int x = 3 defines a variable named x, which contains the integer 3. If I then follow it up with an assignment, x=4, x now contains the integer 4. The key thing is that we didn't replace the variable. We don't have a new "variable x whose value is now 4," we merely replaced the value of x with a new value.
Now let's move to objects. Objects are useful because often you need one "thing" to be referenced from many places. For example, if you have a document open in an editor and want to send it to the printer, it'd be nice to only have one document, referenced both by the editor and the printer. That'd save you having to copy it more times than you might want.
However, because you don't want to copy it more than once, we can't just put an object in a variable. Variables hold onto a value, so if two variables held onto an object, they'd have to make two copies, one for each variable. References are the go-between that resolves this. References are small, easily copied values which can be stored in variables.
So, in code, when you type Dog dog = new Dog(), the new operator creates a new Dog Object, and returns a Reference to that object, so that it can be assigned to a variable. The assignment then gives dog the value of a Reference to your newly created Object.
new Dog() will instantiate an object Dog ie) it will create a memory for the object. You need to access the variable to manipulate some operations. For that you need an reference that is Dog myDog. If you try to print the object it will print an non readable value which is nothing but the address.
myDog -------> new Dog().
I ran across this problem, which has been driving me nuts. In a nutshell, I instantiate two objects of the same class. When I run a method in one object, the other object is affected too as if I called a method on a 2nd object explicitly. I was wondering if someone could please give me a hand on this.
Suppose, I have class Portfolio...
public class Portfolio implements Cloneable {
public ArrayList<Instrument> portfolio;
private String name;
private String description;
public Portfolio() {
portfolio = new ArrayList<Instrument>();
}
public Portfolio(Portfolio copyFrom) {
//attempt to copy the object by value
this.portfolio = (ArrayList<Instrument>) copyFrom.portfolio.clone();
this.name = copyFrom.name;
this.description = copyFrom.description;
}
public void applyStress(Stress stress) {
this.portfolio.set(0,this.portfolio.get(0)+1;
}
1st constructor is used to instantiate an object, etc. 2nd constructor is used to copy an object by value.
A method applyStress is used to run through sum calculations. in our case I simplified the method, so that it does nothing but adds +1 to whatever is in the object.
So I would instantiate an object as
Portfolio p = new Portfolio();
then I would assign to a portfolio field, some instruments;
p.portfolio = someInstrumentList;
then I would copy by value the portfolio p into pCopy:
Portfolio pCopy = new Portfolio(p);
So at this time I am have two objects that are the same. Further one is a copy-by-value object. Changing values of fields in pCopy does not affect same fields in p.
Now, when I run a method applyStress on p, then the values of the instrument list in pCopy will also change.
In other words, if p.portfolio.get(0) == 1, then after p.applyStress, I would expect to see that p.portfolio.get(0) is 2 and pCopy.portfolio.get(0) is 1
But what I see instead is p.portfolio.get(0) is 2 and pCopy.portfolio.get(0) is also 2
I do not understand why this happens. It is not the static modifier issue, as there is no static modifiers. Anyone has any ideas?
The clone method applied to you your ArrayList reference does a shallow copy, not a deep copy. This implies that whatever you had in the original collection is shared by the cloned one.
This means that you need to clone every instrument as well, or provide a copy constructor for every one of them.
this.portfolio = new ArrayList<Instrument>();
for(Instrument toBeCopiedInstrument : copyFrom.portfolio){
this.portfolio.add(new Instrument(toBeCopiedInstrument ));
}
By default .clone() does what is called a shallow copy, this means it just copies a reference to the objects that are held in the List that is being cloned, it doesn't actually copy the objects themselves to new instances.
What you need to do is implement a custom deep copy for the List and each of the items held in the list. But deep clone is a broken concept and implementation in Java.
A copy constructor isn't a really good pattern in Java either, because you end up copying references as well in most cases and every object you inject to the constructor has to follow the same copy constructor semantics all the way down the chain. Unlike C++, this is manual, tedious, unmaintainable and error prone process!
.clone() and implements Cloneable are some of the most complex to get correct concepts in Java. They are rarely needed in well designed applications. That is, if you are using .clone() you are probably doing it wrong. If making bit wise copies of your objects are part of your design for something other than storage, you might want to revisit your design.
Josh Bloch on Design
Object's clone method is very tricky. It's based on field copies, and
it's "extra-linguistic." It creates an object without calling a
constructor. There are no guarantees that it preserves the invariants
established by the constructors. There have been lots of bugs over the
years, both in and outside Sun, stemming from the fact that if you
just call super.clone repeatedly up the chain until you have cloned an
object, you have a shallow copy of the object. The clone generally
shares state with the object being cloned. If that state is mutable,
you don't have two independent objects. If you modify one, the other
changes as well. And all of a sudden, you get random behavior.
Immutable
A better pattern is to make everything immutable. That way you don't need separate instances, you can share instances until they need to change, then they change and you have a new instance with the new data, that can be shared without any side effects.
I'm trying to keep my address the same, since I have a JList pointing towards listAccts. How do I make ListAccts have the same address space? Basically, how do I copy this object?
public class BankEngine extends AbstractListModel {
/** holds the accounts inside the bank engine */
private ArrayList<Account> listAccts;
/** holds all the actions the user has done. */
private ArrayList<Action> actions;
/** holds old versions of the bank. */
private ArrayList<ArrayList<Account>> oldEngines;
/*****************************************************************
* Constructor that creates a new BankEngine, the core of the project
******************************************************************/
public BankEngine() {
listAccts = new ArrayList<Account>();
// actions = new ArrayList<Action>();
oldEngines = new ArrayList<ArrayList<Account>>();
oldEngines.add(listAccts);
}
public void undo() {
if (oldEngines.size() == 0) {
} else {
listAccts = oldEngines.get(oldEngines.size()-1); <--- I want this to have the same listAccts pointer.
}
All the objects in a java process share the same address space i.e. the address space of the running JVM
If I understand correctly, you want to ensure that listAccts refers to the same physical object throughout the lifetime of your code. Unless you assign listAccts to refer to a different object (in code you haven't shown us), this is a given.
After oldEngines.add(listAccts) is executed, oldEngines will contain a reference to the same object listAccts is referring to. However, listAccts is not changed in any way - it still refers to the exact same object!
So - again: unless you reassign listAccts in code you haven't shown us - the line
listAccts = oldEngines.get(oldEngines.size()-1);
looks totally unnecessary to me. In fact, it may be confusing you, if you have added other elements to oldEngines in the meantime, as then its last element won't anymore refer to the same object listAccts does.
Note also that Java doesn't have pointers, only references. All non-primitive (object) variables are actually references, not by-value copies of an object. And the JVM can actually change the physical memory location of objects under the hood, updating all references to these objects. We have no way to notice this, because there is no way to get the actual physical memory address from a reference (at least within Java - I guess you could do it using e.g. JNI). A reference is a higher level of abstraction than a pointer - it is not a memory address. This is why terms like address space are meaningless in Java.
Update
what I'm trying to do is make it so that the last oldEngine is now replacing what is the current listAccts.
If you mean to change the listAccts reference to point to the last element in oldEngine, you are already doing that. If you mean to copy the contents of the last element in oldEngine into the current listAccts object (overwriting its current contents), try
listAccts.clear();
listAccts.addAll(oldEngines.get(oldEngines.size()-1));
If you mean you want listAccts to essentially be the same object as it was before, i.e. you don't want to create a new list, then what you need to do is:
listAccts.addAll(oldEngines.get(oldEngines.size() - 1));
i.e., manipulate your existing list rather than creating a new object.
My problem was I was passing along the same old listAccts to the array list, without saying "new". Even when I did say "new" i was passing along the accounts inside of listAccts, so the arraylist would be new, but the accounts inside of the new array list would be the ones I wanted to have backups of. What I had to do was create a new object from a deep copy using this method.
http://www.javaworld.com/javaworld/javatips/jw-javatip76.html?page=2
Thanks everyone who offered help.