Calling methods on reference variable vs Calling methods on a new object - java

I'm having confusion in calling a non-static method
class A {
void doThis() {}
public static void main(String... arg) {
A a1 = new A();
a1.doThis(); // method - 1
new A().doThis(); // method - 2
}
}
I know that both method-1 and method-2 will call doThis(), but is there any functional difference?

There won't be any difference in execution of those methods but in case of new A().doThis() your're going to lose the reference to the instance of an object you've invoked the method on and you won't be able to use it further in your code. All the changes this method could've done to internal state of the instance will be lost.
In case of A a1 = new A(); a1.doThis(); you're going to preserve the instance of an object (in variable a1) and potential changes made to its state made by method doThis(). Then you'll be able to continue working with this object.

Is there any functional difference?
Both will behave in the same way.
The second option doesn't allow you to reuse that instance again. It may be convenient and concise in one-line return statements (for instance, consider the builder pattern where each constructing method returns a half-initialised instance):
return new Builder().a().b().build();
or if an object was created only to perform a defined action once.
What will be the reference of a new object in method-2?
It is no longer exist (more precisely, we don't have access to it) unless the doThis returns this which you could be able to put in a variable after method execution.
Can I say that method-2 is an improper way of calling a non-static method?
No. Why should we create a variable if this variable will never be used afterwards?

Let's see what the code says in plain English:
A a1 = new A();
a1.doThis();
Create a new instance of A.
Store a reference to it in the variable a1.
Call doThis() on our instance.
Whereas new A().doThis(); reads as:
Create a new instance of A.
Call doThis() on our instance.
So the only difference is whether you store it in a local variable or not. If you don't use the value in the variable any more, then that difference doesn't matter. But if you want to call another method on the same object, let's say a1.doThat(), then you're in trouble with the second solution, as you haven't got a reference to the original instance any more.
Why would you want to use the same object? Because methods can change the internal state of the object, that's pretty much what being an object is about.

Lets take a look at both these methods one by one.
Method-1
A a1 = new A();
a1.doThis();
In method-1, you have a reference of newly created instance of A, i.e a1 and you can call as many methods on this instance of A using this reference a1. Basically you can reuse that particular instance of A by using its reference a1.
Method-2
new A().doThis();
However in method-2, you don't have any variable that stores the reference of your newly created instance of A. How will you refer to that particular instance of A if you have to call any other method on that particular instance of A ? You will not be able to re-use that instance of A if you create an instance using method-2 and you will lose that instance as soon as it is used.

case1:
A a1 = new A();
a1.doThis();
The above two line means object created and doThis(); executed but still object available in the heap memory.
case2:
new A().doThis();
A class object created and doThis(); executed after immediately GC(GarbageColletor) will activate to remove the A object from the heap memory bcz it's a non-referenced object and we can call this object as an anonymous object.

Related

Java - How many instance-methods created in memory when create multiple instances?

Java - I mean do instances share same instance method in memory?For example:
public class Test {
private int a;
private int b;
public Test(int a , int b){
this.a = a;
this.b = b;
}
/* instance method - sum() */
public int sum(){
return a+b;
}
public static void man(String[] args) {
Test t1 = new Test(3,4);
Test t2 = new Test(5,6);
t1.sum();
t2.sum();
}
}
I know when apply new keyword to a class, class variables (properties) will be copied. So instances can have their own property values separately.
But how about method? will it also make a copy? If so, just waste memory resources, because the methods are always same.
what happended in JVM when using a new keyword ? thanks very much!
NOTE: official doc reference is highly preferred :)
But how about method? will it also make a copy? If so, just waste
memory resources, because the methods are always same.
No, there will always be a single copy of each method (in the method area of the JVM). This applies for both static and non-static methods.
Are there some kindly people tell me what happended in JVM when using
a new keyword ? thanks very much!
Simply put, a new Object is created in the heap space by calling the appropriate constructor. A reference to that object is returned.
Methods of a class is stored on stack in .class instance which stores all methods of a class. Only one copy is created for method and it is invoked by all instance of the class.JVM keeps reference of all methods defined in a class and linked it with instance when it calls a method.
what happended in JVM when using a new keyword ?
When we simply put 'new' keyword it creates an object on the heap.
All instances share the same code.
If you compile your Java class and create an instance inside of another class of it, they will call the function on the same Java class (.class)-File.
Of course virtual calls make things somewhat more complex, but basically instance method is like a static method with additional implicit this parameter. Calling t1.sum() is like calling sum(t1) (with additional null check for t1). No reason to duplicate the method for every possible parameter value.

Constructors does not have any return types but then how object is created?

According to the definitions of constructors they don't have any return types,but while creating object we often do A a = new A(); which is responsible for creating the object a.
A a=new A();
Can anyone help me understanding the issue,what is actually happening in the case of constructors while creation of Object.
Constructors don't have return types, correct. But the expression new A() does have a result: A reference to the newly-created object.
Here's what happens with new A():
An object is created
It's given the type A
The relevant A constructor is called with this referring to that new object
Once initialization is done, the expression completes
The result of the expression is the reference to the new object
This process is described in this tutorial on the Oracle Java site.
In many ways, it would be more accurate to call constructors initializers: The construction happens because of the new operator, not the constructor.
The fact that constructors don't actually do the construction is made particularly clear when an object is processed by multiple constructors, as is very common. Consider:
List<String> m = new LinkedList<String>();
One object is created (ignoring any fields the list may need to initialize), but five different constructors get called to initialize that one object, because LinkedList<E> subclasses java.util.AbstractSequentialList<E> which subclasses java.util.AbstractList<E> which subclasses java.util.AbstractCollection<E> which subclasses java.lang.Object, and each of those classes has to get its chance to initialize its part of the object that was created. So in order:
JVM creates the object
Object() is called to initialize Object stuff
AbstractCollection() is called to initialize its stuff
Then AbstractList()
Then AbstractSequentialList()
Then LinkedList()
And then finally the resulting (one) object's reference becomes the result of the new expression
One object, but five constructors required to initialize it. :-)
Constructors need not to return anything. They just constructs the current instance. That's all their job, part of object creation.
Creating objects:
A a = new A();
Declaration: The code set in bold are all variable declarations that associate a variable name with an object type.
Instantiation: The new keyword is a Java operator that creates the object.
Initialization: The new operator is followed by a call to a constructor, which initializes the new object.
Constructor declarations look like method declarations—except
that they use the name of the class and have no return type - from
the java constructor docs
To understand the constructor, it is similarly important to understand how it differs from a method.
Constructors have one purpose in life: to initialize the new object and it's fields. Nothing more. The new keyword handles the creation of memory space.
You shouldn't consider new A() to be a call to the constructor, because there are more things that happen, than just the constructor running. The major steps, when you run new A() are these.
A chunk of memory is set aside - just enough for storing an object of class A.
The constructor is run.
A reference to the chunk of memory that was set aside is returned.
So the constructor itself isn't actually returning anything - and it's an error to have return this; or anything similar inside the constructor.
Return statement inside a constructor doesn't logically makes sense because the purpose of the constructor is to perform initialization. The object has not been created yet, the actual construction of the object happens in JVM.

Difference between "passing reference after assigning an object" and "passing object using new keyword" to a method in java?

What difference does it makes?
Let's think we have a method in java as following:
void demoMethod(MyClass mc){
// some operations
}
First type:
demoMethod(new MyClass()); // directly passing an object
Second type:
MyClass mc = new MyClass();
demoMethod(mc); // passing reference of an object
No difference in terms of the method's behavior on that reference. The first code can semantically translate to the second one. Eventually, the object created using new MyClass() needs to be stored somewhere so that it can be re-loaded and passed to the method.
However, using the second code you can re-use the reference.
It doesn't make any difference for demoMethod. Actually in both cases you are passing reference only.
However if you want to use the information after demoMethod does some operation in the calling method, you can't do that in first type.
Assume your demoMethod sets a property of your MyClass object to true or false, you don't have any way to find out what it's value is set to.
So, you can do something like
demoMethod(mc);
if(mc.isMyProperty()==true)
System.out.println("mc is changed");

Difference between call to a method in Java?

I just want to make clear that to call a function in two forms like
By creating an object and calling the method by using that object.
Without creating a object calling the function.
I mean for instance i have a class like
Class A{
public int callMethod(){
return 2;
}
}
Now I am creating another class to call the method callMethod defined in the Class A
Class B {
public static void main(String[] args) throws ParseException {
A a = new A();
//1st form to call the method
int aa = a.callMethod()
System.out.println(aa);
//2nd form to call the method
aa = new A().callMethod();
System.out.println(aa);
}
}
here in the first statement after creation of a object i am calling the callMethod() of class A by using the class object of A. And in the second time i am calling the method directly without creating the object class A. In the first form calling the method it is damn sure that we are creating the object and occupies some space in the memory for the object. Then what about the second form calling the method? Will it take any object creation? Which one is quicker? can anyone give me the clarifications on this.
When you use new keyword and constructor, in this case, new A(), it is creating a new object.
And in the second time i am calling the method directly without
creating the object class A.
That's not true - the object is still created, it only has no name you can refer to afterwards.
Both of your ways are creating an instance of the object but in second case you don't have variable to point to the object if you want to access the second object later you can not do it
In the second code you are creating an instance of A and it is occupying space on the stack.
The first code will require that you instantiate A on the heap space (Unless you instantiate it from static code, for example:
static {
A a = new A();
}
)
You are creating objects in the BOTH the methods. The statement
new A()
creates a new object and then you are calling a function.
You should also know that objects DO NOT get different memory space for methods. All the objects of a class share the same memory space for methods. so it really doesnt matter about the space.
If you want to call a function without using a object, you should make the function static, that way you cam call the function without actually using an object.
hope this helps.
Read about stack space and heap space in java
In java we have references referring to objects on heap space,
In both cases, it is creating object on heap space but in first case
you have reference stored on stack space with A a ("a" is reference)
So in same method or any other methos to which this reference is
passed can refer to the original object (first object created) from
heap space...
In second case you are calling methos directly on new obj which has no
reference stored on stack space to refer it afterwards like in first
case.
Both are same..!!
When you write
new A();
here Compiler calls the Non-parameterized constructor (if it is not written by programmer compiler calls the default constructor )
like:
A()
{
//i am default constructor
super();
}
note: here super(); call the immediate super-class default constructor which is the Object class and object is created.
A a = new A();
here object is created and you assign that object to reference 'a';

when is "this" assigned memory location and at what point can a method be called in java

class A
{
B b;
public A()
{
b = new B(this);
//initialization of class A variables
}
public void meth1()
{
}
}
class B
{
A a;
public B(A a)
{
this.a = a;
}
}
I know that this reference shouldn't be passed in this way,but what happens if this is done
Some other class calls the class A constructor. when is the "this" reference actually allocated memory? would it be assigned memory as soon as A's constructor is called before even super() is called.
Suppose class B is a thread and since B has A's reference can B call the methods on A before A's constructor doesn't even return if "this" reference is not allocated memory yet.
The memory for the object is allocated before any constructor is executed. Otherwise the constructor would have not place to write the values of the variables.
Therefore you can pass out a reference to the current object (a.k.a this) to other pieces of code inside the constructor.
As you noted, the object is not fully constructed at that time and it's a bad idea to actually do that, but "just" because the values of the object can be in an inconsistent state. The memory is already allocated and reserved for that object at this point in time.
this is just a reference to the "current object", which you could think of as just another parameter that any non-static method gets. In fact in that's actually how the JVM treats it. See JVMS §2.6.1 Local Variables:
On instance method invocation, local variable 0 is always used to pass a reference to the object on which the instance method is being invoked (this in the Java programming language).
So the direct answer to "when is this allocated" is effectively: Whenever you call a method on an object.
this refers to current object and any object is allocated memory using "new"
The memory is allocated when JVM is processing new instruction. If for example your code looks like:
A a = new A();
^
here the memory for A is allocated
It indeed could be a problem to pass this to B. Constructor of B can invoke instance method of A before the constructor of A has been finished. You should move line to the end of constructor of A to avoid possible problems. Alternatively you could manage the object lifecycle from outside using setters.
this is assigned before the constructor is called. In fact, the super() call is not necessary. It only ensures that the creation stuff of the parent class is done, which doesn't matter if the parent class is Object. Also, A's methods are usable as soon as the object is created (even before the constructor is called) so if B got the reference to A in the constructor, it can use A's methods just like A itself in the constructor. Just be sure to make A's methods so that they can be used when A is not fully initialized, or just create and start B after the initialization is complete.
As long as you don't modify A or call methods on A or it's members in the constructor of B it will work. ( See other answers)
If you call a method on an not completely initialized object (after construction) it's not defined what happens. Especially if you use multiple threads (see memory barrier).
More on this topic:
How do JVM's implicit memory barriers behave when chaining constructors?

Categories