what exactly happen in jvm when i create an object in java? - java

To my understanding if i am writing
Car a3=new Car()
This statement will create a handle named a3 in jvm stack with all its properties in JVM heap.
IF this is correct i am wondering how call by value works.
So, if i create a method checkMethod(Car c) and call it by saying checkMethod(a3);
suppose our car is
public class Car{
int a=0;
public int getpar(){
return a;
}
}
in checkMethod i try to access a using a3.a = 5; so i changed the value of a3.a
it will show me in the calling class as well as it was pointing to the same fields that jvm created in the heap.
But when i do a3= null; in the calling method and go back again in the method from which i was calling
checkMethod(a3) and try to see this object it is not null?
Why it behaved differently as compared to property of object that is a???

checkMethod(a3);
Pass a copy of a value which is a reference to object instance of Car
Inside method...
a3.a = 5
Using a3, modify object instance of Car which is identified by a3 ( which is a copy of original a3).
a3 = null
Set the reference to null ( copy)
When this happens, only the copy you passed to your method will point to null. But the original a3 still points to your object instance of Car.

Why it behaved differently as compared to property of object that is a?
Because Java is (pure) call by value. You cannot manipulate the value of the parameter within the callee context. You always gets a local copy in the calling context.

On method calls, Java passes a copy of the reference.
So when setting a3 to null, it only set its copy of the reference to null and the other copies that are stored else where.

The whole trick is this: Java passes references by value :)

Related

Java object creation difference

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.

How to properly copy objects [duplicate]

This question already has answers here:
How do I copy an object in Java?
(23 answers)
Closed 8 years ago.
This might have been asked already but since I am not so sure how to phrase it I could not find it.
Essentially
Suppose we have the class a, (see code below), and we want to copy an instance of it, a1, to another instance a2.
So, in my main I would have a1.copy(a2)
I know that using copy2 method this will work. However copy1 will not. I just would like to clarify why this is. Is it because the parameter is just a "copy" of the object, so the object itself (a2) is not altered.
class a {
private int val;
public class(int val){
this.val = val;
}
public void copy1(a obj){
obj = this;
}
public void copy2(a obj) {
obj.val = this.val;
}
}
The key to understand your problem is that Java's method call is always pass-by-value, not by reference.
When you call a.copy1(b), Java copies a value of b's reference(say it is called b_copy, please note that b_copy points to the same memory location as b), and then pass b_copy to the method copy1.
And in your method of copy1, Java only changes the reference of b_copy.
public void copy1(b_copy){
b_copy=a;
}
So now :
b_copy: b_copy=a;
b: b does not change at all;
When the method ends,b_copy dies. So nothing changes on b!
While a.copy2(b) manipulates on the object itself, but it still copies a new value of b(say b_copy again) and pass into copy2
public void copy2(b_copy){
b_copy.val = a.val;
}
Since b_copy points to the same memory of b, so when you do changes on b_copy.val, you also does the same on b.val itself. That's the reason why b changes.
So now :
b_copy: b_copy, but b_copy's val changes
b: b's val also changes, since b_copy is points to the b's memory location;
And then when method ends, b_copy dies, and b has changed!
You may find more discussion on Is Java "pass-by-reference" or "pass-by-value"?
And you may also need How do I copy an object in Java?
When you call the method copy1(), the parameter is a copy of the reference of the object a obj. When you set it to this (obj = this;) the copy of the reference of the object is replaced by the current object, but the original object and the reference to the object at the place you are calling the copy1() method stays the same. You just change the copy of the reference of the object.
When you call the method copy2(), no reference work is done there, and you are doing one by one matching of the variables (properties of the objects) and there is no copy of reference work there. You are changing the object itself. In this case, this.val = obj.val; would also work.
For more understanding, check this topic and check how other languages like C or C++ handle parameter passing issue.
I think you might want to look into how parameters are passed in Java.
For primitive variables, they are passed by value. If I recall correctly, this means that a temporary value is passed and any changes to the variable in the function update only the temporary variable.
However, objects are passed by reference. This means that instead of the entire object, essentially a pointer to where the object is in memory is passed.
What this means is that updating an object's variables produces lasting effects on that object. Additionally, if you set one object equal to another object, you're really just setting the memory references to be the same (a byproduct of this is that the values of the variables in the objects are then linked).
This explains why the first function fails to do what you want (you're setting the memory locations to be the same). And the second succeeds (you're performing a deep copy into a new memory address).
Your reasoning is correct. When you pass an object to a method (as you do in copy1), all you are doing is creating another reference to the same object. If you override this reference, as copy1 does, it just means that that reference now points to a different object - it does not, and can not, change the original object.

Recursive pass in object by reference? JAVA

So I have an algorithm that forces me to pass in an object as a parameter recursively and on different depths of the recursion it sets the values of the object. The problem is Java isn't allowing me to do this because they pass in by value or something else that is just messing me up. How can you make sure that the object passed in retains the value set?
You never pass an object as an argument in Java. You either pass a reference or a primitive value. The argument is always passed by value. Java doesn't have pass-by-reference at all.
If you're passing in a reference to an object, and you want to make sure the code you call doesn't change the data within that object, your options are:
Create a copy and pass in a reference to that instead
Make your type immutable in the first place.
EDIT: Just to make it clear, if you have:
Foo f = new Foo();
then the value of f is not a Foo object. It's a reference to a Foo object. If you now call:
doSomething(f);
then the value of f is copied as the original value of the parameter within doSomething. That behaviour is basically the definition of pass-by-value. There's nothing doSomething can to do change the value of f - it will still refer to the same object afterwards. The data within that object may have changed, but it won't be a different object.
In a real-world analogy: if I give you a copy of my address, you can go and paint the front door, but you can't change where I live.
As Jon states, all non-primitives are passed by passing a copy of the reference. You don't have a choice. So your recursive method should be able to update the object if it is mutable. HOWEVER, you can't reassign a reference and expect it to propagate back up the call stack. And remember that Strings are not mutable.
In other words, if you do the following, you have not changed the object that was passed:
void myMethod(Object o){
o = new Object();
}
The above changes the local reference to o but does not change the caller's reference to o. If you need to do something like this you would need to return o.

JAVA class null value

I would like to ask if there is anyways in java to ensure that a class can never be instantiated as null. But i want to do this inside the class. For example
class A
{
I can never be null
}
class B
{
A a = null ; << No you cant. Does not compute :P
}
Thanks in advance.
This is not, generally speaking, possible. When you declare:
A a = null;
A a2 = new A();
Both a and a2 are references, not actual objects. Think of a reference as a pointer, but one that does not support C-style pointer arithmetic.
A a = null;
sets up a reference (a pointer) that can point to an object of type A, but is currently initialized to null. It's not possible to have class A ensure that there are never any null references to things of type A.
No.
No. You cannot do that. What is your use case, maybe we can suggest an alternative.
We often talk about a null object but that is totally misleading. An object is an object and only a variable can hold the value null (instead of a reference to an object).
Something like a null object simply doesn't exist in Java.
If we do a
A a = new A();
we create a new instance of A and store a reference (a pointer) to this instance at the variable. The variables value is now some sort of address of the location of this new object. If the instantiation fails (an exception is thrown) then no assignement will be made and the variable keeps its old value. Which may be null - but again, this just tells us that the variable doesn't hold a reference to any object.

Java reference-type in parameter

Why doesn't this change the initial object:
public class Foo
{
Bar item = new Item(5);
public changeBar(Bar test){
test = new Item(4);
}
public run(){
changeBar(item);
}
}
In this case item doesn't get changed. How is this possible? I mean, you're passing the reference as parameter in the method, so I'd say assigning a new value to it, means the initial item would also be changed.
Can someone explain to me how this works.
=======================================
however, my question is the following:
the following does work right?
public changeBar2(Bar test){
test.parameter = "newValue";
}
I don't see how that's different.
Consider a thought experiment:
changeBar(null);
Would your code above change the value of null?
The answer to your question is that although your Bar object is passed "by reference", this is different from passing the reference itself by value. In Java, all parameters are passed by value, even when they are themselves references to other objects.
public changeBar(Bar test){
test = new Item(4);
}
changeBar(item);
Here the value in item in copied to test. So as of now, both item, test are pointing to same object(s). Inside the method, test is pointing to a different location which doesn't affect the item. You are passing by value and not by reference.
public changeBar2(Bar test){
test.parameter = "newValue";
}
The above modifies the object that is passed because both the test and item are referring to the same object.
So, test can totally either point to a new object or modify the object was earlier referring to. Both are different and are valid.
Parameters in Java are ALWAYS passed-by-value.
At the beginnning of function changeBar() test is a reference to item, but then you overwrite it with a reference to a newly created item. You therefore only overwrite the local variable with a different reference, but don't change the referenced by object.
test in changeBar is basically as pointer. So when you assign it, you are changing the pointer.
Here is an article: http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
You are giving the method the reference to this object, that is, its address so to speak. So this address is stocked in a variable named test.
Then your method erases what is written in the test variable, and writes instead the address of a new Item object it created. Nothing here changes anything to the initial Item object, nor to the references to it that are outside the method's scope.
I guess I am pretty approximative here and I will be glad to get corrected.

Categories

Resources