I'm new to OOP concepts in Java. What is the difference between these two incidents?
1.
ClassName obj_name = new ClassName();
obj_name.method();
2.
new ClassName().method();
A good explanation is much appreciated. Thanks
In Option(1), you are still having/holding the reference to the object, so you can reuse that reference to access/call the other members(method/variables) of the object (class).
In Option (2), you don't have the reference (i.e., reference has been lost), so you will NOT be able to use it again.
One point to remember is that if you want to access the same object members multiple times, you need to hold the reference (use option 1 above), rather than creating the object (option 2) again and again (which is costly operation i.e., occupies memory).
Please refer the below link for more details:
https://docs.oracle.com/javase/tutorial/java/javaOO/usingobject.html
The reference variable obj_name hold the object of ClassName.through which you can call the instance method of ClassName through reference variable obj_name.
Whene ever we create an object and dont assign its reference to any reference variable its Known as Anonymous object instantiation.The Advantage of this type of instantiation is that you can only do the limited operation on that.Like you can call a single method.
If you want to perform mopre operation then reference varaibale which hold the object is better approach.If you have multiple method in your class and you want to use them then option 1 is right choice.
for details please go through this Link
While they might accomplish the same objective for the first call, the two approaches do fundamentally different things in terms of class definition and instantiation.
ClassName object = new ClassName();`
object.method();`
This is a case of instantiation. You create a new ClassName object which possesses certain instance fields and methods. It can call these methods, and the result may cause its instance fields to change.
ClassName.method();
On the other hand, this approach does not create an instance of the class. Instead, it calls method as a class attribute. Thus, the result can change fields in ClassName, but it won't necessarily existing fields in already-instantiated objects.
public class ClassName(){
public int attr = 0;
public ClassName(){}
public void setAttr(int value){
this.attr = value;
}
public void method(int value){
this.attr += value;
}
}
Now, using the first approach, we can create a newObj and call newObj.method(100). This will increase newObj's instance variable attr by 100.
To see the difference between the two approaches, let's use setAttr(200) to change the object's attr to 200.
Next, if we just use ClassName.method(100), the class's attr value will become 100 for all future instances of ClassName. So if we create ClassName nextObj = new ClassName(), this new instance of ClassName will have attr of 100, while newObj will still have attr of 200.
Hopefully this explains the core difference between the two approaches.
in option 1 you are creating an object with new keyword
followed by constructor and that object is referenced by class_name
obj_name variable so obj_name is pointing to that object.
In option 2 you not referencing to that object. just you make an
object and call the method with no references so that object is
eligible for garbage collection.
Related
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
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.
Class A {
// blah blah
}
Now, whenever we need to create an instance of this class, we do:
A a = new A();
In c++ there are two ways:
1. A a(10); // Created on Stack. Assume that the constructor takes an int argument
2. A a = new A(); // Created on Heap
How do you create user defined Java objects on stack?
No it isn't. All method-local primitive types and references are put on the stack, all objects are put in the heap. No ifs and buts about it.
One reason I can think why they did is that it removes one commonly made error: you pass the stack-based object to a method that stores a reference to that object. Then the object goes out of scope, is removed from the stack, and the reference points to something undefined. Next when you want to access the "object" through the reference, you're in a world of hurt since the object is no longer there - and nobody knows what is.
Let's say SList is a super class of TailList.
If I execute the following codes,
SList s;
TailList t = new TailList();
s = t;
is this same as doing SList s = new TailList();?
Now, is static type of t still TailList?
When you execute SList s = new TailList();, what happens is the following:
new TailList() is invoked, creating a new object which the constructor of TailList is run for. When the constructor finishes, an anonymous TailList reference is returned.
The anonymous TailList reference is assigned to s.
Since a TailList is inheriting from SList, you can also refer to it by that. The reference to the object doesn't change the object itself.
Imagine I put a trash bin somewhere, and then tell someone who doesn't know of that object being a trash bin that I put a "container" at that location. The trash bin is indeed a container, but that person only knows that it's a container. This doesn't change the fact that it's a trash bin, but the other person can't safely assume that he can put trash in there, or that it is scheduled to be emptied at any time, therefore he wouldn't know to invoke this functionality on the "container" that he is refering to.
So for instance, let's say we have the following code:
String s = "Hello there";
Object o = s;
o is now refering to a String object, but is treating it as an "object", it doesn't know that it has a length, or that it contains characters, even though it does.
s on the other hand, while still refering to the same object that o is refering to, knows that this object is a String, and can use String functionality on that object.
If we wanted to, we could assume that o is a String by a mechanism called "casting":
String s2 = (String)o;
We now refer to the object referenced by o as a String. All of this changes nothing for the object itself, it's all a mere change in reference. As if, for the previous analogy, the person who was told about the mysterious "container", will assume that the container is more specifically a "trash bin". We could also make a wrong assumption, that the container is a packaging container
Integer i = (Integer)o; // throws ClassCastException
Fortunately, when we assume wrongly in Java, we get a ClassCastException, unlike in real life where if you put your items into a trash bin while refering to it as a packaging container your belongings will be thrown to garbage.
Or perhaps, what is confusing you is that first assignment. Well, new TailList() part of SList s = new TailList(); by itself is a static invocation of the constructor of TailList, and it will always return a TailList reference. The assignment that comes afterwards will still refer to the TailList object that was constructed by the invocation.
TL;DR
Yes, it's the same thing.
The object will be instantiated as TailList, and the assignment won't change that. (It would be a neat trick if the language could change the implementation class on assignment ;) )
For example, you can always go
TailList t = new TailList();
Object o = t;
Does that make it more clear? The object is still the same implementation class. It' not going to change to an Object, even though we're referencing it that way.
You could always do a System.err.println(s.getClass().getName()) and see.
BTW this is actually polymorphism rather than inheritance, because you're referencing the object as a class higher in the hierarchy. Inheritance would be if you called t.slistMethod() without overriding it.
In statically typed object-oriented languages, both objects and variables have an associated type.
The type of a variable (the 'static type') is specified by the programmer when declaring the variable. It never changes.
The type of the object referenced by the variable (the 'runtime type') must be either the same or a subtype of the variable's declared type. An object never changes type, but the variable may be assigned a different object of a different type.
The first snippet declares two variables, s of type SList and t of type TailList. It creates an object of type TailList and stores a reference to it in both variables.
The second snippet declares a variable s of type SList, creates an object of type TailList, and stores a reference to it in s.
The end result in both cases is that s contains a reference to an object of type TailList. The difference is that in the first snippet there is an additional reference to the object stored in variable t (which still has a static type of TailList).
Is
TailList t = new TailList();
SList s = t;
The same as
SList s = new TailList();
Yes, except there's no separate reference of type TailList held to the new object, so you'll only be able to access methods from SList (unless you cast).
Let's consider the following code in Java.
package obj;
final class First
{
public int x;
public First(int x)
{
this.x=x;
}
}
final class Second
{
public Second(First o)
{
o.x=10;
}
}
final public class Main
{
public static void main(String[] args)
{
First f=new First(50);
Second s=new Second(f);
System.out.println("x = "+f.x);
}
}
In the above code, we are supplying a value 50 through the statement First f=new First(50); which is being assigned to a class member x of type int in the constructor body in the class First.
In the class Second, the object f of the class First is being passed through the statement Second s=new Second(f); and we are modifying the value of the instance variable x held in that object to 10 which will affect the original object f because in Java objects are always passed by reference and not by value.
In some specific situations, it may be crucial not to allow such changes to the original objects. Is there any mechanism in Java that may allow us to prevent such modifications? (that might allow us to pass objects by value)
No, the object isn't being passed at all in Second. The reference is being passed by value.
Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object.
It sounds like you want to create a copy of an existing object, then pass a reference to that new object to the method (by value). Quite what constitutes a "copy" will depend on the data in the class. (You may be able to get away with a shallow copy, or you may need to go deeper etc.)
No, there aren't. I would say that your example is not a very good one: if you want to ensure that something doesn't change, don't provide ways to change it. Causing the change to be lost afterwards is misleading at best.
First f=new First(50);
Second s=new Second(f);
in first line you are create a reference variable of Object type First and in 2nd line it is pass to Class Second
So as Jon Skeet say in java "Java always uses pass-by-value, but the value of any expression is only ever a primitive type or a reference - never an object."
And if if u don't want to change the value of property then u must be pass new object of class First
Because if u have a reference of any class then u can change the property of that class ..
Or u can create a copy of that object which is at the end creating a new object of First Class