What is the difference between a variable, object, and reference? [duplicate] - java

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().

Related

In java, is an object considered a variable?

One source I am studying defines an array as "a collection of variables under one name, where the variables are accessed by index numbers."
But then I realized that you can have an array of objects (or an array of pointers to objects, at least).
This got me to wonder what a variable is defined as in java, as I did not consider an object to be a variable. Jenkov Tutorials cites a variable as being "a piece of memory that can contain a data value."
And since I believe an object fits this definition, is an object considered a variable?
Calling an array a "collection of variables" is arguably stretching the definition already. But an array is certainly a collection of references that can be made to point to different objects in memory, and each such reference can reasonably be called a variable.
Asking "is an object a variable" is a little weird in the first place. In Object o = new Object(), o is clearly a variable, though remember it's a reference to an object in the heap, not the object itself.
Honestly, "variable" is a pretty flexible, ill-defined term -- is a field a variable? The return result of a method? It depends on who's talking and what fuzzy definition they're using today.
is an object considered a variable?
No, these are two distinct things.
The first one (the object) is the value and the second one (the variable) is a way to reference an object, generally to use it (invoking a series of method on it for example).
For example when you write :
new Dog()
You instantiate a Dog. Nice. But suppose you want feed it if it is hungry.
You cannot if you have not a way to chain a series of method on this object.
By storing the reference of the Dog in a dog variable you can do it :
Dog dog = new Dog();
if (dog.isHungry()){
dog.feed();
}
Jenkov Tutorials cites a variable as being "a piece of memory that
can contain a data value."
It says the same thing.
But this :
One source I am studying defines an array as "a collection of
variables under one name, where the variables are accessed by index
numbers."
is rather misleading.
An array is an object that has a state that contains, among other things, elements of the array.
The way which the elements are referenced in is a implementation detail of the Array class and I would not affirm that each element is stored in a specific variable.
An object is created when you call the constructor with the reserved word new.
For example:
Object a = new Object();
a will be the variable of that new object created and will go to reserved memory for that object. You are instantiating that new variable and that variable is associated with that object.
Hope might this will help you to understand it better...
class Bulb
{
private int w;
public void setWattage(int e)
{
w=e;
}
public int getWattage()
{
return w;
}
}
class Test
{
public static void main(String args[])
{
Bulb b[];
b=new Bulb[2];
b[0]=new Bulb();
b[1]=new Bulb();
b[0].setWattage(60);
b[1].setWattage(100);
System.out.println(b[0].getWattage());
}
}
here b[0] and b[1] are reference variables who have the address of two Bulb objects

New instance of class created or just space in memory allocated?

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.

Working of dot operator when applied to objects

I was going through the working principles of the dot operator, which is the same as the * operator in C++, that is they both solve our purpose of dereferencing. When we apply dot to some class, or some object, then we enter the heap of the class/object, and have an access to the static variables or methods of class, and instance variables as well in the case of methods.
Now my doubt is that while I'm applying some method to an object by using the dot operator, that is, now I'm able to use the data stored inside the instance variables inside my methods. But now when I try and change the data of those instance variables, it tends to change. From what I know I can't change the data inside the methods of languages like java where things work pass by value.
Can someone explain this to me?
From what I know I can't change the data inside the methods of languages like java where things work pass by value.
Java is pass by value ... but in the case of reference types (arrays or instances of classes), the values are references.
The dot "operator" is performing an operation on a reference.
In Java, you normally just forget about the fact that there is a reference there and (mentally) treat the object and the reference to the object as being the same thing. (There is a reference available, even in the case of instance method referring to the fields if the current object ... it is this, and you are using it implicitly.)
This is different to C++. In C++, object types and reference (pointer) typed are distinct, and their values (objects and references) are likewise distinct. You can create, pass, and use, an object without having a reference to it. And the compiler does not prevent you from having a reference that doesn't actually point to an object. The behavior of the latter is undefined ...
Also in C++, you can create and pass references to things that are not objects. For example, you can pass a reference to a variable. You can't do that in Java.

C++ member variable semantics

I have a rather simple question with an inkling as to what the answer is.
My generalized question:
What is actually going on when you declare a member variable, be it public or private, and for all permutations of variable types, e.g. static vs const vs regular variables?
class some_class
{
private:
static const std::string str;
public:
...
}
I have kind of realized that in C++ there is no notion of a non-variable, that is, a non-constructed variable as I was kind of taught to believe exists with languages like Java. The same may also be true in Java, however it is not the way I was taught to think of things so I'm trying to come up with the correct way to think of these non-initialized variables.
public class main {
public static void main(String[] args) {
String str; // A kind of non-variable, or non-constructed variable (refers to null).
str = new String(); // Now this variable actually refers to an object rather than null, it is a constructed variable.
}
}
Since C++ allows you to initialize member variables in the constructor through initializer lists, and I have proven to myself via use of a debugger that the variable doesn't exist before it is initialized through the initializer list (either explicitly or by default), what is, then, actually going on behind the scenes when you declare the member variable?
Tricky question -- it's ambiguous depending on perspective.
From a pseudo-machine perspective, normally adding a non-static plain old data type to a class makes that class type bigger. The compiler also figures out how to align it and relative memory offsets to address it relative to the object in the resulting machine code.
This is pseudo-machine level because at the machine level, data types don't actually exist: just raw bits and bytes, registers, instructions, things like that.
When you add a non-primitive user-defined type, this recurses and the compiler generates the instructions to access the members of the member and so on.
From a higher level, adding members to a class makes the member accessible from instances (objects) of the class. The constructor initializes those members, and the destructor destroys them (recursively triggering destructors of members that have non-trivial destructors, and likewise for constructors in the construction phase).
Yet your example is a static member. For static members, they get stored in a data segment at the machine level and the compiler generates the code to access those static members from the data segment.
Some of this might be a bit confusing. C++ shares its legacy with C which is a hardware-level language, and its static compilation and linking affects its design. So while it can go pretty high-level, a lot of its constructs are still tied to how the hardware, compiler, and linker does things, whereas in Java, the language can make some more sensible choices in favor of programmer convenience without a language design that somewhat reflects all of these things.
Yes and no.
A variable of class type in Java is really a pointer. Unlike C and C++ pointers, it doesn't support pointer arithmetic (but that's not essential to being a pointer--for example, pointers in Pascal didn't support arithmetic either).
So, when you define a variable of class type in Java: String str;, it's pretty much equivalent to defining a pointer in C++: String *str;. You can then assign a new (or existing) String object to that, as you've shown.
Now, it's certainly possible to achieve roughly the same effect in C++ by explicitly using a pointer (or reference). There are differences though. If you use a pointer, you have to explicitly dereference that pointer to get the object to which it refers. If you use a reference, you must initialize the reference--and once you do so, that reference can never refer to any object other than the one with which it was initialized.
There are also some special rules for const variables in C++. In many cases, where you're just defining a symbolic name for a value:
static const int size = 1234;
...and you never use that variable in a way that requires it to have an address (e.g., taking its address), it usually won't be assigned an address at all. In other words, the compiler will know the value you've associated with that name, but when compilation is finished, the compiler will have substituted the value anywhere you've used that name, so the variable (as such) basically disappears (though if you have the compiler generate debugging information, it'll usually retain enough to know and display its name/type correctly).
C++ does have one other case where a variable is a little like a Java "zombie" object that's been declared but not initialized. If you move from an object: object x = std::move(y);, after the move is complete the source of the move (y in this case) can be in a rather strange state where it exists, but about all you can really do with it is assign a new value to it. Just for example, in the case of a string, it might be an empty string--but it also could retain exactly the value it had before the move, or it could contain some other value (e.g., the value that the destination string held before the move).
Even that, however, is a little bit different--even though you don't know its state, it's still an object that should maintain the invariants of its class--for example, if you move from a string, and then ask for the string's length, that length should match up with what the string actually contains--if (for example) you print it out, you don't know what string will print out, but you should not get an equivalent of a NullPointerException--if it's an empty string, it just won't print anything out. If it's a non-empty string, the length of the data that's printed out should match up with what its .size() indicates, and so on.
The other obviously similar C++ type would be a pointer. An uninitialized pointer does not point to an object. The pointer itself exists though--it just doesn't refer to anything. Attempting to dereference it could give some sort of error message telling you that you've attempted to use a null pointer--but unless it has static storage duration, or you've explicitly initialized it, there's no guarantee that it'll be a null pointer either--attempting to dereference it could give a garbage value, throw an exception, or almost anything else (i.e., it's undefined behavior).

Keeping the address space the same in java

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.

Categories

Resources